diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-02-21 11:44:29 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2020-02-25 11:32:09 +0100 |
| commit | 35f7a3a3430f7285839d8b90439d6de9cdba025c (patch) | |
| tree | 0a5958daf5cee3acbfa2c5df57a11d1f568fead4 | |
| parent | b7a2e7e67d09dd1ac3190b3812c855372ca84cc8 (diff) | |
| download | mullvadvpn-35f7a3a3430f7285839d8b90439d6de9cdba025c.tar.xz mullvadvpn-35f7a3a3430f7285839d8b90439d6de9cdba025c.zip | |
Slightly improve SetupAPI-specific error messages
| -rw-r--r-- | windows/driverlogic/driverlogic.vcxproj | 2 | ||||
| -rw-r--r-- | windows/driverlogic/driverlogic.vcxproj.filters | 2 | ||||
| -rw-r--r-- | windows/driverlogic/src/driverlogic.cpp | 31 | ||||
| -rw-r--r-- | windows/driverlogic/src/error.cpp | 163 | ||||
| -rw-r--r-- | windows/driverlogic/src/error.h | 14 |
5 files changed, 197 insertions, 15 deletions
diff --git a/windows/driverlogic/driverlogic.vcxproj b/windows/driverlogic/driverlogic.vcxproj index 657e58d9eb..fd9ba06616 100644 --- a/windows/driverlogic/driverlogic.vcxproj +++ b/windows/driverlogic/driverlogic.vcxproj @@ -97,9 +97,11 @@ </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="src\driverlogic.cpp" /> + <ClCompile Include="src\error.cpp" /> <ClCompile Include="src\stdafx.cpp" /> </ItemGroup> <ItemGroup> + <ClInclude Include="src\error.h" /> <ClInclude Include="src\stdafx.h" /> <ClInclude Include="src\targetver.h" /> </ItemGroup> diff --git a/windows/driverlogic/driverlogic.vcxproj.filters b/windows/driverlogic/driverlogic.vcxproj.filters index ba18d9617c..b9c494e241 100644 --- a/windows/driverlogic/driverlogic.vcxproj.filters +++ b/windows/driverlogic/driverlogic.vcxproj.filters @@ -9,9 +9,11 @@ <ItemGroup> <ClCompile Include="src\driverlogic.cpp" /> <ClCompile Include="src\stdafx.cpp" /> + <ClCompile Include="src\error.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="src\stdafx.h" /> <ClInclude Include="src\targetver.h" /> + <ClInclude Include="src\error.h" /> </ItemGroup> </Project>
\ No newline at end of file diff --git a/windows/driverlogic/src/driverlogic.cpp b/windows/driverlogic/src/driverlogic.cpp index 02cc10f20a..3cb30ab91b 100644 --- a/windows/driverlogic/src/driverlogic.cpp +++ b/windows/driverlogic/src/driverlogic.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "error.h" #include <iostream> #include <sstream> #include <string> @@ -108,7 +109,7 @@ std::optional<std::wstring> GetDeviceRegistryStringProperty( // TODO: Check if there may be other causes. if (ERROR_INVALID_DATA != lastError) { - THROW_WINDOWS_ERROR(lastError, "SetupDiGetDeviceRegistryPropertyW"); + THROW_SETUPAPI_ERROR(lastError, "SetupDiGetDeviceRegistryPropertyW"); } return std::nullopt; @@ -132,7 +133,7 @@ std::optional<std::wstring> GetDeviceRegistryStringProperty( if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "Failed to read device property"); + THROW_SETUPAPI_ERROR(GetLastError(), "Failed to read device property"); } return std::make_optional(buffer.data()); @@ -168,7 +169,7 @@ std::wstring GetDeviceStringProperty( if (ERROR_INSUFFICIENT_BUFFER != lastError) { - THROW_WINDOWS_ERROR(lastError, "SetupDiGetDevicePropertyW"); + THROW_SETUPAPI_ERROR(lastError, "SetupDiGetDevicePropertyW"); } } @@ -191,7 +192,7 @@ std::wstring GetDeviceStringProperty( if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "Failed to read device property"); + THROW_SETUPAPI_ERROR(GetLastError(), "Failed to read device property"); } return buffer.data(); @@ -224,7 +225,7 @@ std::wstring GetDeviceInstanceId( if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetDeviceInstanceIdW"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiGetDeviceInstanceIdW"); } return deviceInstanceId.data(); @@ -243,7 +244,7 @@ std::wstring GetNetCfgInstanceId(HDEVINFO devInfo, const SP_DEVINFO_DATA &devInf if (hNet == INVALID_HANDLE_VALUE) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiOpenDevRegKey"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiOpenDevRegKey"); } std::vector<wchar_t> instanceId(MAX_PATH + 1); @@ -289,13 +290,13 @@ bool DeleteDevice(HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) auto status = SetupDiSetClassInstallParamsW(devInfo, data, &rmdParams.ClassInstallHeader, sizeof(rmdParams)); if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiSetClassInstallParamsW"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiSetClassInstallParamsW"); } status = SetupDiCallClassInstaller(DIF_REMOVE, devInfo, data); if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiCallClassInstaller"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCallClassInstaller"); } return true; @@ -312,7 +313,7 @@ void ForEachNetworkDevice(const std::optional<std::wstring> hwId, std::function< if (INVALID_HANDLE_VALUE == devInfo) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetClassDevsW"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiGetClassDevsW"); } common::memory::ScopeDestructor cleanupDevList; @@ -335,7 +336,7 @@ void ForEachNetworkDevice(const std::optional<std::wstring> hwId, std::function< break; } - THROW_WINDOWS_ERROR(lastError, "Enumerating network adapters"); + THROW_SETUPAPI_ERROR(lastError, "Enumerating network adapters"); } if (hwId.has_value()) @@ -417,7 +418,7 @@ void CreateTapDevice() const auto deviceInfoSet = SetupDiCreateDeviceInfoList(&classGuid, 0); if (INVALID_HANDLE_VALUE == deviceInfoSet) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiCreateDeviceInfoList"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCreateDeviceInfoList"); } common::memory::ScopeDestructor scopeDestructor; @@ -441,7 +442,7 @@ void CreateTapDevice() if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiCreateDeviceInfoW"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCreateDeviceInfoW"); } status = SetupDiSetDeviceRegistryPropertyW( @@ -454,7 +455,7 @@ void CreateTapDevice() if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiSetDeviceRegistryPropertyW"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiSetDeviceRegistryPropertyW"); } // @@ -468,7 +469,7 @@ void CreateTapDevice() if (FALSE == status) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiCallClassInstaller"); + THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCallClassInstaller"); } Log(L"Created new TAP adapter successfully"); @@ -531,7 +532,7 @@ ATTEMPT_UPDATE: } } - THROW_WINDOWS_ERROR(lastError, "UpdateDriverForPlugAndPlayDevicesW"); + THROW_SETUPAPI_ERROR(lastError, "UpdateDriverForPlugAndPlayDevicesW"); } // diff --git a/windows/driverlogic/src/error.cpp b/windows/driverlogic/src/error.cpp new file mode 100644 index 0000000000..bdbc8e050d --- /dev/null +++ b/windows/driverlogic/src/error.cpp @@ -0,0 +1,163 @@ +#include "stdafx.h" +#include "error.h" +#include <string> +#include <iomanip> +#include <sstream> +#include <map> +#include <setupapi.h> +#include <libcommon/error.h> + + +#define SETUPAPI_ERROR_TABLE_ENTRY(constant) { constant, #constant } + +namespace +{ + +const std::map<uint32_t, const char *> setupApiCodeToString = +{ + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_EXPECTED_SECTION_NAME), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_BAD_SECTION_NAME_LINE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_SECTION_NAME_TOO_LONG), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_GENERAL_SYNTAX), + // + // Inf runtime errors + // + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_WRONG_INF_STYLE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_SECTION_NOT_FOUND), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_LINE_NOT_FOUND), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_BACKUP), + // + // Device Installer/other errors + // + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_ASSOCIATED_CLASS), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_CLASS_MISMATCH), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DUPLICATE_FOUND), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_DRIVER_SELECTED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_KEY_DOES_NOT_EXIST), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_DEVINST_NAME), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_CLASS), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVINST_ALREADY_EXISTS), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVINFO_NOT_REGISTERED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_REG_PROPERTY), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_INF), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_SUCH_DEVINST), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_CANT_LOAD_CLASS_ICON), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_CLASS_INSTALLER), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DI_DO_DEFAULT), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DI_NOFILECOPY), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_HWPROFILE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_DEVICE_SELECTED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVINFO_LIST_LOCKED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVINFO_DATA_LOCKED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DI_BAD_PATH), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_CLASSINSTALL_PARAMS), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_FILEQUEUE_LOCKED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_BAD_SERVICE_INSTALLSECT), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_CLASS_DRIVER_LIST), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_ASSOCIATED_SERVICE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_DEFAULT_DEVICE_INTERFACE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVICE_INTERFACE_ACTIVE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVICE_INTERFACE_REMOVED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_BAD_INTERFACE_INSTALLSECT), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_SUCH_INTERFACE_CLASS), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_REFERENCE_STRING), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_MACHINENAME), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_REMOTE_COMM_FAILURE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_MACHINE_UNAVAILABLE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_CONFIGMGR_SERVICES), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_PROPPAGE_PROVIDER), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_SUCH_DEVICE_INTERFACE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DI_POSTPROCESSING_REQUIRED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_COINSTALLER), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_COMPAT_DRIVERS), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_DEVICE_ICON), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_INF_LOGCONFIG), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DI_DONT_INSTALL), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_FILTER_DRIVER), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NON_WINDOWS_NT_DRIVER), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NON_WINDOWS_DRIVER), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_CATALOG_FOR_OEM_INF), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVINSTALL_QUEUE_NONNATIVE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NOT_DISABLEABLE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_CANT_REMOVE_DEVINST), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INVALID_TARGET), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DRIVER_NONNATIVE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_IN_WOW64), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_SET_SYSTEM_RESTORE_POINT), + + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_SCE_DISABLED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_UNKNOWN_EXCEPTION), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_PNP_REGISTRY_ERROR), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_REMOTE_REQUEST_UNSUPPORTED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NOT_AN_INSTALLED_OEM_INF), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_INF_IN_USE_BY_DEVICES), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DI_FUNCTION_OBSOLETE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_NO_AUTHENTICODE_CATALOG), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_AUTHENTICODE_DISALLOWED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_AUTHENTICODE_TRUSTED_PUBLISHER), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVICE_INSTALLER_NOT_READY), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DRIVER_STORE_ADD_FAILED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DEVICE_INSTALL_BLOCKED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DRIVER_INSTALL_BLOCKED), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_WRONG_INF_TYPE), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_FILE_HASH_NOT_IN_CATALOG), + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_DRIVER_STORE_DELETE_FAILED), + + // + // Setupapi exception codes + // + SETUPAPI_ERROR_TABLE_ENTRY(ERROR_UNRECOVERABLE_STACK_OVERFLOW), +}; + +const char *IsolateFilename(const char *filepath) +{ + const auto slash = strrchr(filepath, '/'); + const auto backslash = strrchr(filepath, '\\'); + + if (nullptr == slash && nullptr == backslash) + { + return filepath; + } + + return max(slash, backslash) + 1; +} + +} // anonymous namespace + +bool IsSetupApiError(uint32_t code) +{ + const auto it = setupApiCodeToString.find(code); + return (setupApiCodeToString.end() != it); +} + +const char * FormatSetupApiError(uint32_t code) +{ + const auto it = setupApiCodeToString.find(code); + + if (setupApiCodeToString.end() == it) + { + return nullptr; + } + + return it->second; +} + +void ThrowSetupApiError(const char *operation, uint32_t code, const char *file, size_t line) +{ + const auto message = FormatSetupApiError(code); + + if (nullptr != message) + { + std::stringstream ss; + ss << operation << ": " << message + << " (0x" << std::setw(8) << std::setfill('0') << std::hex << code << ")"; + common::error::Throw(ss.str().c_str(), file, line); + } + + // Fallback: Treat as a regular Windows error + common::error::Throw(operation, code, file, line); +} diff --git a/windows/driverlogic/src/error.h b/windows/driverlogic/src/error.h new file mode 100644 index 0000000000..4895345887 --- /dev/null +++ b/windows/driverlogic/src/error.h @@ -0,0 +1,14 @@ +#pragma once + +#include <cstdint> + + +bool IsSetupApiError(uint32_t code); +const char *FormatSetupApiError(uint32_t code); + +[[noreturn]] void ThrowSetupApiError(const char *operation, uint32_t code, const char *file, size_t line); + +#define THROW_SETUPAPI_ERROR(errorCode, operation)\ +{\ + ThrowSetupApiError(operation, errorCode, __FILE__, __LINE__);\ +} |
