summaryrefslogtreecommitdiffhomepage
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
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.
-rw-r--r--dist-assets/windows/installer.nsh140
-rw-r--r--windows/driverlogic/driverlogic.vcxproj2
-rw-r--r--windows/driverlogic/driverlogic.vcxproj.filters2
-rw-r--r--windows/driverlogic/src/device.cpp170
-rw-r--r--windows/driverlogic/src/device.h7
-rw-r--r--windows/driverlogic/src/driverlogic.cpp115
-rw-r--r--windows/driverlogic/src/service.cpp93
-rw-r--r--windows/driverlogic/src/service.h2
-rw-r--r--windows/driverlogic/src/version.cpp125
-rw-r--r--windows/driverlogic/src/version.h30
10 files changed, 105 insertions, 581 deletions
diff --git a/dist-assets/windows/installer.nsh b/dist-assets/windows/installer.nsh
index 7b1f552e2e..c02ade6ed5 100644
--- a/dist-assets/windows/installer.nsh
+++ b/dist-assets/windows/installer.nsh
@@ -23,10 +23,6 @@
# Return codes from driverlogic
!define DL_GENERAL_SUCCESS 0
!define DL_GENERAL_ERROR 1
-!define DL_ST_DRIVER_NONE_INSTALLED 2
-!define DL_ST_DRIVER_SAME_VERSION_INSTALLED 3
-!define DL_ST_DRIVER_OLDER_VERSION_INSTALLED 4
-!define DL_ST_DRIVER_NEWER_VERSION_INSTALLED 5
# Log targets
!define LOG_INSTALL 0
@@ -74,7 +70,6 @@
# The working directory cannot be deleted, so make sure it's set to $TEMP.
SetOutPath "$TEMP"
- RMDir /r "$TEMP\mullvad-split-tunnel"
Delete "$TEMP\wintun.dll"
Delete "$TEMP\mullvad-wireguard.dll"
Delete "$TEMP\driverlogic.exe"
@@ -88,6 +83,20 @@
!define CleanupTempFiles '!insertmacro "CleanupTempFiles"'
#
+# ExtractDriverlogic
+#
+# Extract device setup tools to $TEMP
+#
+!macro ExtractDriverlogic
+
+ SetOutPath "$TEMP"
+ File "${BUILD_RESOURCES_DIR}\..\windows\driverlogic\bin\x64-$%CPP_BUILD_MODE%\driverlogic.exe"
+
+!macroend
+
+!define ExtractDriverlogic '!insertmacro "ExtractDriverlogic"'
+
+#
# ExtractWireGuard
#
# Extract Wintun and WireGuardNT installer into $TEMP
@@ -97,7 +106,6 @@
SetOutPath "$TEMP"
File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\wintun\wintun.dll"
File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\wireguard-nt\mullvad-wireguard.dll"
- File "${BUILD_RESOURCES_DIR}\..\windows\driverlogic\bin\x64-$%CPP_BUILD_MODE%\driverlogic.exe"
!macroend
@@ -119,23 +127,6 @@
!define ExtractMullvadSetup '!insertmacro "ExtractMullvadSetup"'
#
-# ExtractSplitTunnelDriver
-#
-# Extract split tunnel driver and associated files into $TEMP\mullvad-split-tunnel
-#
-!macro ExtractSplitTunnelDriver
-
- SetOutPath "$TEMP\mullvad-split-tunnel"
- File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\split-tunnel\mullvad-split-tunnel.cat"
- File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\split-tunnel\mullvad-split-tunnel.inf"
- File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\split-tunnel\mullvad-split-tunnel.sys"
- File "${BUILD_RESOURCES_DIR}\..\windows\driverlogic\bin\x64-$%CPP_BUILD_MODE%\driverlogic.exe"
-
-!macroend
-
-!define ExtractSplitTunnelDriver '!insertmacro "ExtractSplitTunnelDriver"'
-
-#
# RemoveWintun
#
# Try to remove Wintun
@@ -314,97 +305,6 @@
!define InstallService '!insertmacro "InstallService"'
#
-# InstallSplitTunnelDriver
-#
-# Install split tunnel driver
-#
-# Returns: 0 in $R0 on success, otherwise an error message in $R0
-#
-!macro InstallSplitTunnelDriver
-
- log::Log "InstallSplitTunnelDriver()"
-
- Push $0
- Push $1
-
- log::Log "Searching for and evaluating already installed Split Tunneling driver"
- nsExec::ExecToStack '"$TEMP\mullvad-split-tunnel\driverlogic.exe" st-evaluate "$TEMP\mullvad-split-tunnel\mullvad-split-tunnel.inf"'
-
- Pop $0
- Pop $1
-
- ${If} $0 == ${DL_ST_DRIVER_NONE_INSTALLED}
- log::Log "No currently installed Split Tunneling driver"
- Goto InstallSplitTunnelDriver_new_install
- ${OrIf} $0 == ${DL_ST_DRIVER_SAME_VERSION_INSTALLED}
- log::Log "Up-to-date Split Tunneling driver already installed"
- Goto InstallSplitTunnelDriver_success
- ${OrIf} $0 == ${DL_ST_DRIVER_OLDER_VERSION_INSTALLED}
- log::Log "An older version of the Split Tunneling driver is installed"
- Goto InstallSplitTunnelDriver_force_install
- ${OrIf} $0 == ${DL_ST_DRIVER_NEWER_VERSION_INSTALLED}
- log::Log "A newer version of the Split Tunneling driver is installed"
- Goto InstallSplitTunnelDriver_force_install
- ${Else}
- IntFmt $0 "0x%X" $0
- StrCpy $R0 "Failed to search for and evaluate driver: error $0"
- log::LogWithDetails $R0 $1
- Goto InstallSplitTunnelDriver_return
- ${EndIf}
-
- InstallSplitTunnelDriver_new_install:
-
- log::Log "Installing Split Tunneling driver"
- nsExec::ExecToStack '"$TEMP\mullvad-split-tunnel\driverlogic.exe" st-new-install "$TEMP\mullvad-split-tunnel\mullvad-split-tunnel.inf"'
-
- Pop $0
- Pop $1
-
- ${If} $0 != ${DL_GENERAL_SUCCESS}
- IntFmt $0 "0x%X" $0
- StrCpy $R0 "Failed to install driver: error $0"
- log::LogWithDetails $R0 $1
- Goto InstallSplitTunnelDriver_return
- ${EndIf}
-
- Goto InstallSplitTunnelDriver_success
-
- InstallSplitTunnelDriver_force_install:
-
- #
- # Would be possible to check driver state here and warn the user if driver is engaged.
- #
-
- log::Log "Installing Split Tunneling driver"
- nsExec::ExecToStack '"$TEMP\mullvad-split-tunnel\driverlogic.exe" st-force-install "$TEMP\mullvad-split-tunnel\mullvad-split-tunnel.inf"'
-
- Pop $0
- Pop $1
-
- ${If} $0 != ${DL_GENERAL_SUCCESS}
- IntFmt $0 "0x%X" $0
- StrCpy $R0 "Failed to install driver: error $0"
- log::LogWithDetails $R0 $1
- Goto InstallSplitTunnelDriver_return
- ${EndIf}
-
- InstallSplitTunnelDriver_success:
-
- log::Log "InstallSplitTunnelDriver() completed successfully"
-
- Push 0
- Pop $R0
-
- InstallSplitTunnelDriver_return:
-
- Pop $1
- Pop $0
-
-!macroend
-
-!define InstallSplitTunnelDriver '!insertmacro "InstallSplitTunnelDriver"'
-
-#
# RemoveSplitTunnelDriver
#
# Reset and remove split tunnel driver
@@ -417,7 +317,7 @@
Push $1
log::Log "Removing Split Tunneling driver"
- nsExec::ExecToStack '"$TEMP\mullvad-split-tunnel\driverlogic.exe" st-remove'
+ nsExec::ExecToStack '"$TEMP\driverlogic.exe" st-remove'
Pop $0
Pop $1
@@ -893,12 +793,9 @@
${RemoveRelayCache}
${RemoveApiAddressCache}
- SetOutPath "$TEMP"
- File "${BUILD_RESOURCES_DIR}\..\windows\driverlogic\bin\x64-$%CPP_BUILD_MODE%\driverlogic.exe"
+ ${ExtractDriverlogic}
${RemoveAbandonedWintunAdapter}
-
- ${ExtractSplitTunnelDriver}
- ${InstallSplitTunnelDriver}
+ ${RemoveSplitTunnelDriver}
${If} $R0 != 0
MessageBox MB_OK "$R0"
@@ -1208,11 +1105,10 @@
${ClearFirewallRules}
${RemoveCurrentDevice}
+ ${ExtractDriverlogic}
${ExtractWireGuard}
${RemoveWintun}
${RemoveWireGuardNt}
-
- ${ExtractSplitTunnelDriver}
${RemoveSplitTunnelDriver}
log::SetLogTarget ${LOG_VOID}
diff --git a/windows/driverlogic/driverlogic.vcxproj b/windows/driverlogic/driverlogic.vcxproj
index cc46c1ac72..3172356a60 100644
--- a/windows/driverlogic/driverlogic.vcxproj
+++ b/windows/driverlogic/driverlogic.vcxproj
@@ -104,7 +104,6 @@
<ClCompile Include="src\service.cpp" />
<ClCompile Include="src\stdafx.cpp" />
<ClCompile Include="src\util.cpp" />
- <ClCompile Include="src\version.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\devenum.h" />
@@ -115,7 +114,6 @@
<ClInclude Include="src\stdafx.h" />
<ClInclude Include="src\targetver.h" />
<ClInclude Include="src\util.h" />
- <ClInclude Include="src\version.h" />
<ClInclude Include="src\wintun.h" />
<ClInclude Include="src\wireguard.h" />
</ItemGroup>
diff --git a/windows/driverlogic/driverlogic.vcxproj.filters b/windows/driverlogic/driverlogic.vcxproj.filters
index 9665231376..bd73d30029 100644
--- a/windows/driverlogic/driverlogic.vcxproj.filters
+++ b/windows/driverlogic/driverlogic.vcxproj.filters
@@ -13,7 +13,6 @@
<ClCompile Include="src\device.cpp" />
<ClCompile Include="src\service.cpp" />
<ClCompile Include="src\log.cpp" />
- <ClCompile Include="src\version.cpp" />
<ClCompile Include="src\util.cpp" />
<ClCompile Include="src\devenum.cpp" />
</ItemGroup>
@@ -24,7 +23,6 @@
<ClInclude Include="src\device.h" />
<ClInclude Include="src\service.h" />
<ClInclude Include="src\log.h" />
- <ClInclude Include="src\version.h" />
<ClInclude Include="src\util.h" />
<ClInclude Include="src\wintun.h" />
<ClInclude Include="src\devenum.h" />
diff --git a/windows/driverlogic/src/device.cpp b/windows/driverlogic/src/device.cpp
index e38709f01d..71abb56266 100644
--- a/windows/driverlogic/src/device.cpp
+++ b/windows/driverlogic/src/device.cpp
@@ -38,47 +38,6 @@ constexpr SIZE_T ST_DRIVER_STATE_STARTED = 1;
// Onwards.
//
-void
-ThrowUpdateException
-(
- DWORD lastError,
- const char *operation
-)
-{
- if (ERROR_DEVICE_INSTALLER_NOT_READY == lastError)
- {
- bool deviceInstallDisabled = false;
-
- try
- {
- const auto key = common::registry::Registry::OpenKey
- (
- HKEY_LOCAL_MACHINE,
- L"SYSTEM\\CurrentControlSet\\Services\\DeviceInstall\\Parameters"
- );
-
- deviceInstallDisabled = (0 != key->readUint32(L"DeviceInstallDisabled"));
- }
- catch (...)
- {
- }
-
- if (deviceInstallDisabled)
- {
- throw common::error::WindowsException
- (
- "Device installs must be enabled to continue. "
- "Enable them in the Local Group Policy editor, or "
- "update the registry value DeviceInstallDisabled in "
- "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DeviceInstall\\Parameters]",
- lastError
- );
- }
- }
-
- THROW_SETUPAPI_ERROR(lastError, operation);
-}
-
} // anonymous namespace
std::wstring
@@ -196,135 +155,6 @@ GetDeviceNetCfgInstanceId
}
void
-CreateDevice
-(
- const GUID &classGuid,
- const std::wstring &deviceName,
- const std::wstring &deviceHardwareId
-)
-{
- Log(L"Attempting to create device");
-
- const auto deviceInfoSet = SetupDiCreateDeviceInfoList(&classGuid, 0);
-
- if (INVALID_HANDLE_VALUE == deviceInfoSet)
- {
- THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCreateDeviceInfoList");
- }
-
- common::memory::ScopeDestructor scopeDestructor;
-
- scopeDestructor += [&deviceInfoSet]()
- {
- SetupDiDestroyDeviceInfoList(deviceInfoSet);
- };
-
- SP_DEVINFO_DATA devInfoData {0};
- devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-
- auto status = SetupDiCreateDeviceInfoW
- (
- deviceInfoSet,
- deviceName.c_str(),
- &classGuid,
- nullptr,
- 0,
- DICD_GENERATE_ID,
- &devInfoData
- );
-
- if (FALSE == status)
- {
- THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCreateDeviceInfoW");
- }
-
- status = SetupDiSetDeviceRegistryPropertyW
- (
- deviceInfoSet,
- &devInfoData,
- SPDRP_HARDWAREID,
- reinterpret_cast<const BYTE *>(deviceHardwareId.c_str()),
- static_cast<DWORD>(deviceHardwareId.size() * sizeof(wchar_t))
- );
-
- if (FALSE == status)
- {
- THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiSetDeviceRegistryPropertyW");
- }
-
- //
- // Create a devnode in the PnP HW tree
- //
- status = SetupDiCallClassInstaller
- (
- DIF_REGISTERDEVICE,
- deviceInfoSet,
- &devInfoData
- );
-
- if (FALSE == status)
- {
- THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCallClassInstaller");
- }
-
- Log(L"Created new device successfully");
-}
-
-void
-InstallDriverForDevice
-(
- const std::wstring &deviceHardwareId,
- const std::wstring &infPath
-)
-{
- Log(L"Attempting to install new driver");
-
- DWORD installFlags = 0;
- BOOL rebootRequired = FALSE;
-
- for (;;)
- {
- auto result = UpdateDriverForPlugAndPlayDevicesW
- (
- nullptr,
- deviceHardwareId.c_str(),
- infPath.c_str(),
- installFlags,
- &rebootRequired
- );
-
- if (FALSE != result)
- {
- break;
- }
-
- const auto lastError = GetLastError();
-
- if (ERROR_NO_MORE_ITEMS == lastError
- && (0 == (installFlags & INSTALLFLAG_FORCE)))
- {
- Log(L"Driver installation/update failed. Attempting forced install.");
- installFlags |= INSTALLFLAG_FORCE;
-
- continue;
- }
-
- ThrowUpdateException(lastError, "UpdateDriverForPlugAndPlayDevicesW");
- }
-
- //
- // Driver successfully installed or updated
- //
-
- std::wstringstream ss;
-
- ss << L"Device driver update complete. Reboot required: "
- << rebootRequired;
-
- Log(ss.str());
-}
-
-void
UninstallDevice
(
const EnumeratedDevice &device
diff --git a/windows/driverlogic/src/device.h b/windows/driverlogic/src/device.h
index b8bc0e7f41..4dc8c4500d 100644
--- a/windows/driverlogic/src/device.h
+++ b/windows/driverlogic/src/device.h
@@ -39,13 +39,6 @@ CreateDevice
);
void
-InstallDriverForDevice
-(
- const std::wstring &deviceHardwareId,
- const std::wstring &infPath
-);
-
-void
UninstallDevice
(
const EnumeratedDevice &device
diff --git a/windows/driverlogic/src/driverlogic.cpp b/windows/driverlogic/src/driverlogic.cpp
index 2fdcc3046c..895272fa4f 100644
--- a/windows/driverlogic/src/driverlogic.cpp
+++ b/windows/driverlogic/src/driverlogic.cpp
@@ -3,7 +3,6 @@
#include "device.h"
#include "service.h"
#include "log.h"
-#include "version.h"
#include "wintun.h"
#include "wireguard.h"
#include "devenum.h"
@@ -20,8 +19,6 @@
namespace
{
-constexpr wchar_t SPLIT_TUNNEL_HARDWARE_ID[] = L"Root\\mullvad-split-tunnel";
-
DEFINE_GUID(WFP_CALLOUTS_CLASS_ID,
0x57465043, 0x616C, 0x6C6F, 0x75, 0x74, 0x5F, 0x63, 0x6C, 0x61, 0x73, 0x73);
@@ -30,11 +27,7 @@ constexpr wchar_t SPLIT_TUNNEL_DEVICE_NAME[] = L"Mullvad Split Tunnel Device";
enum ReturnCode
{
GENERAL_SUCCESS = 0,
- GENERAL_ERROR = 1,
- ST_DRIVER_NONE_INSTALLED = 2,
- ST_DRIVER_SAME_VERSION_INSTALLED = 3,
- ST_DRIVER_OLDER_VERSION_INSTALLED = 4,
- ST_DRIVER_NEWER_VERSION_INSTALLED = 5
+ GENERAL_ERROR = 1
};
class ArgumentContext
@@ -105,74 +98,6 @@ std::unique_ptr<DeviceEnumerator> CreateSplitTunnelDeviceEnumerator()
}
//
-// CommandSplitTunnelEvaluate()
-//
-// Search for existing device.
-// Evaluate if provided inf can/should be installed.
-//
-ReturnCode CommandSplitTunnelEvaluate(const std::vector<std::wstring> &args)
-{
- ArgumentContext argsContext(args);
-
- argsContext.ensureExactArgumentCount(1);
-
- const auto infPath = argsContext.next();
-
- //
- // Find first matching device
- //
-
- auto enumerator = CreateSplitTunnelDeviceEnumerator();
-
- EnumeratedDevice device;
-
- if (!enumerator->next(device))
- {
- return ReturnCode::ST_DRIVER_NONE_INSTALLED;
- }
-
- //
- // Retrieve driver versions
- //
-
- auto existingVersion = GetDriverVersion(device);
- auto proposedVersion = InfGetDriverVersion(infPath);
-
- //
- // Compare driver versions
- //
-
- switch (EvaluateDriverUpgrade(existingVersion, proposedVersion))
- {
- case DRIVER_UPGRADE_STATUS::WOULD_UPGRADE:
- return ReturnCode::ST_DRIVER_OLDER_VERSION_INSTALLED;
- case DRIVER_UPGRADE_STATUS::WOULD_DOWNGRADE:
- return ReturnCode::ST_DRIVER_NEWER_VERSION_INSTALLED;
- case DRIVER_UPGRADE_STATUS::WOULD_INSTALL_SAME_VERSION:
- return ReturnCode::ST_DRIVER_SAME_VERSION_INSTALLED;
- default:
- Log(L"Unexpected return value from EvaluateDriverUpgrade()");
- }
-
- return ReturnCode::GENERAL_ERROR;
-}
-
-ReturnCode CommandSplitTunnelNewInstall(const std::vector<std::wstring> &args)
-{
- ArgumentContext argsContext(args);
-
- argsContext.ensureExactArgumentCount(1);
-
- const auto infPath = argsContext.next();
-
- CreateDevice(WFP_CALLOUTS_CLASS_ID, SPLIT_TUNNEL_DEVICE_NAME, SPLIT_TUNNEL_HARDWARE_ID);
-
- InstallDriverForDevice(SPLIT_TUNNEL_HARDWARE_ID, infPath);
-
- return ReturnCode::GENERAL_SUCCESS;
-}
-
-//
// CommandSplitTunnelRemove()
//
// Reset driver
@@ -186,48 +111,29 @@ ReturnCode CommandSplitTunnelRemove(const std::vector<std::wstring> &args)
argsContext.ensureExactArgumentCount(0);
+ if (ServiceIsRunning(L"mullvad-split-tunnel"))
+ {
+ ResetDriverState();
+ }
+
//
- // Find first matching device
+ // Uninstall device, if it exists
//
auto enumerator = CreateSplitTunnelDeviceEnumerator();
EnumeratedDevice device;
- if (!enumerator->next(device))
+ if (enumerator->next(device))
{
- Log(L"Could not find split tunnel device");
-
- return ReturnCode::GENERAL_SUCCESS;
+ UninstallDevice(device);
}
- ResetDriverState();
-
- UninstallDevice(device);
-
PokeService(L"mullvad-split-tunnel", true, true);
return ReturnCode::GENERAL_SUCCESS;
}
-//
-// CommandSplitTunnelForceInstall()
-//
-// There's an existing device that needs to be stopped and removed.
-// After this, create a new device and associate the specified inf.
-//
-ReturnCode CommandSplitTunnelForceInstall(const std::vector<std::wstring> &args)
-{
- auto status = CommandSplitTunnelRemove({});
-
- if (ReturnCode::GENERAL_SUCCESS != status)
- {
- return status;
- }
-
- return CommandSplitTunnelNewInstall(args);
-}
-
ReturnCode CommandWintunDeleteDriver(const std::vector<std::wstring> &args)
{
ArgumentContext argsContext(args);
@@ -336,9 +242,6 @@ int wmain(int argc, const wchar_t *argv[])
std::vector<CommandHandler> handlers =
{
- { L"st-evaluate", CommandSplitTunnelEvaluate },
- { L"st-new-install", CommandSplitTunnelNewInstall },
- { L"st-force-install", CommandSplitTunnelForceInstall },
{ L"st-remove", CommandSplitTunnelRemove },
{ L"wintun-delete-driver", CommandWintunDeleteDriver },
{ L"wintun-delete-abandoned-device", CommandWintunDeleteAbandonedDevice },
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]()
diff --git a/windows/driverlogic/src/service.h b/windows/driverlogic/src/service.h
index 87632faf1b..423d16c0f0 100644
--- a/windows/driverlogic/src/service.h
+++ b/windows/driverlogic/src/service.h
@@ -2,6 +2,6 @@
#include <windows.h>
-void WaitUntilServiceStopped(SC_HANDLE service, DWORD maxWaitMs);
+bool ServiceIsRunning(const std::wstring &serviceName);
void PokeService(const std::wstring &serviceName, bool stopService, bool deleteService);
diff --git a/windows/driverlogic/src/version.cpp b/windows/driverlogic/src/version.cpp
deleted file mode 100644
index d7394e224b..0000000000
--- a/windows/driverlogic/src/version.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "stdafx.h"
-#include "version.h"
-#include "device.h"
-#include <setupapi.h>
-#include <initguid.h>
-#include <devpkey.h>
-#include <libcommon/string.h>
-#include <libcommon/memory.h>
-#include <stdexcept>
-
-DRIVER_UPGRADE_STATUS
-EvaluateDriverUpgrade
-(
- const std::wstring &existingVersion,
- const std::wstring &proposedVersion
-)
-{
- //
- // "x.y.z.a"
- //
-
- using namespace common::string;
-
- auto et = Tokenize(existingVersion, L".");
- auto pt = Tokenize(proposedVersion, L".");
-
- auto items = min(et.size(), pt.size());
-
- for (auto index = 0; index < items; ++index)
- {
- auto ev = wcstoul(et[index].c_str(), nullptr, 10);
- auto pv = wcstoul(pt[index].c_str(), nullptr, 10);
-
- if (pv > ev)
- {
- return DRIVER_UPGRADE_STATUS::WOULD_UPGRADE;
- }
-
- if (ev > pv)
- {
- return DRIVER_UPGRADE_STATUS::WOULD_DOWNGRADE;
- }
- }
-
- if (pt.size() > et.size())
- {
- return DRIVER_UPGRADE_STATUS::WOULD_UPGRADE;
- }
-
- if (et.size() > pt.size())
- {
- return DRIVER_UPGRADE_STATUS::WOULD_DOWNGRADE;
- }
-
- return DRIVER_UPGRADE_STATUS::WOULD_INSTALL_SAME_VERSION;
-}
-
-std::wstring
-InfGetDriverVersion
-(
- const std::wstring &filePath
-)
-{
- auto infHandle = SetupOpenInfFileW(filePath.c_str(), nullptr, INF_STYLE_WIN4, nullptr);
-
- if (infHandle == INVALID_HANDLE_VALUE)
- {
- throw std::runtime_error("SetupOpenInfFileW()");
- }
-
- common::memory::ScopeDestructor dtor;
-
- dtor += [infHandle]()
- {
- SetupCloseInfFile(infHandle);
- };
-
- INFCONTEXT infContext { 0 };
-
- auto status = SetupFindFirstLineW(infHandle, L"Version", L"DriverVer", &infContext);
-
- if (status == FALSE)
- {
- throw std::runtime_error("SetupFindFirstLineW()");
- }
-
- DWORD requiredSize;
-
- //
- // This is a multi-value key.
- // 0 = key, 1 = driver date
- //
- const DWORD VersionFieldIndex = 2;
-
- status = SetupGetStringFieldW(&infContext, VersionFieldIndex, nullptr, 0, &requiredSize);
-
- if (status == FALSE || requiredSize < 2)
- {
- throw std::runtime_error("SetupGetStringFieldW()");
- }
-
- std::vector<wchar_t> buffer(requiredSize);
-
- status = SetupGetStringFieldW(&infContext, VersionFieldIndex,
- &buffer[0], static_cast<DWORD>(buffer.size()), nullptr);
-
- if (status == FALSE)
- {
- throw std::runtime_error("SetupGetStringFieldW()");
- }
-
- // Remove null terminator.
- buffer.resize(requiredSize - 1);
-
- return buffer.data();
-}
-
-std::wstring
-GetDriverVersion
-(
- const EnumeratedDevice &device
-)
-{
- return GetDeviceStringProperty(device.deviceInfoSet, device.deviceInfo, &DEVPKEY_Device_DriverVersion);
-}
diff --git a/windows/driverlogic/src/version.h b/windows/driverlogic/src/version.h
deleted file mode 100644
index fc88b3b232..0000000000
--- a/windows/driverlogic/src/version.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include <string>
-#include "device.h"
-
-enum class DRIVER_UPGRADE_STATUS
-{
- WOULD_DOWNGRADE,
- WOULD_INSTALL_SAME_VERSION,
- WOULD_UPGRADE
-};
-
-DRIVER_UPGRADE_STATUS
-EvaluateDriverUpgrade
-(
- const std::wstring &existingVersion,
- const std::wstring &proposedVersion
-);
-
-std::wstring
-InfGetDriverVersion
-(
- const std::wstring &filePath
-);
-
-std::wstring
-GetDriverVersion
-(
- const EnumeratedDevice &device
-);