summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-02-25 12:21:59 +0100
committerDavid Lönnhager <david.l@mullvad.net>2020-02-25 12:21:59 +0100
commit943f4154568ce6892eadcf1b57a9deb436d27e5f (patch)
treef651795fede6c02b8734719754cb1729eaaf8bc8
parent807de13a4577db8d97b8718f43fe9aef6be84b6d (diff)
parent687a2f7bad4aafc55515def59b1ec07a43f1fa50 (diff)
downloadmullvadvpn-943f4154568ce6892eadcf1b57a9deb436d27e5f.tar.xz
mullvadvpn-943f4154568ce6892eadcf1b57a9deb436d27e5f.zip
Merge branch 'improve-device-error-msg'
-rw-r--r--dist-assets/windows/installer.nsh12
-rw-r--r--windows/driverlogic/driverlogic.vcxproj2
-rw-r--r--windows/driverlogic/driverlogic.vcxproj.filters2
-rw-r--r--windows/driverlogic/src/driverlogic.cpp69
-rw-r--r--windows/driverlogic/src/error.cpp165
-rw-r--r--windows/driverlogic/src/error.h14
-rw-r--r--windows/driverlogic/src/stdafx.h5
m---------windows/windows-libraries0
8 files changed, 247 insertions, 22 deletions
diff --git a/dist-assets/windows/installer.nsh b/dist-assets/windows/installer.nsh
index 83dd72a6d4..c7adccc49e 100644
--- a/dist-assets/windows/installer.nsh
+++ b/dist-assets/windows/installer.nsh
@@ -25,8 +25,8 @@
!define MULLVAD_SUCCESS 1
# Return codes from driverlogic
-!define DL_GENERAL_ERROR 0
-!define DL_GENERAL_SUCCESS 1
+!define DL_GENERAL_ERROR -1
+!define DL_GENERAL_SUCCESS 0
# Log targets
!define LOG_FILE 0
@@ -131,8 +131,9 @@
Pop $0
Pop $1
- ${If} $0 == ${DL_GENERAL_ERROR}
- StrCpy $R0 "Failed to remove vanilla TAP adapter"
+ ${If} $0 != ${DL_GENERAL_SUCCESS}
+ IntFmt $0 "0x%X" $0
+ StrCpy $R0 "Failed to remove vanilla TAP adapter: error $0"
log::LogWithDetails $R0 $1
Goto RemoveVanillaTap_return
@@ -194,7 +195,8 @@
Pop $1
${If} $0 != ${DL_GENERAL_SUCCESS}
- StrCpy $R0 "Failed to create virtual adapter"
+ IntFmt $0 "0x%X" $0
+ StrCpy $R0 "Failed to create virtual adapter: error $0"
log::LogWithDetails $R0 $1
Goto InstallTapDriver_return
${EndIf}
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 c92ad51ed6..3e482c196f 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>
@@ -8,6 +9,7 @@
#include <libcommon/guid.h>
#include <libcommon/memory.h>
#include <libcommon/network/nci.h>
+#include <libcommon/registry/registry.h>
#include <libcommon/string.h>
#include <setupapi.h>
#include <initguid.h>
@@ -28,8 +30,8 @@ constexpr wchar_t TAP_BASE_ALIAS[] = L"Mullvad";
enum ReturnCodes
{
- GENERAL_ERROR,
- GENERAL_SUCCESS
+ GENERAL_SUCCESS = 0,
+ GENERAL_ERROR = -1
};
struct NetworkAdapter
@@ -107,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;
@@ -131,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());
@@ -167,7 +169,7 @@ std::wstring GetDeviceStringProperty(
if (ERROR_INSUFFICIENT_BUFFER != lastError)
{
- THROW_WINDOWS_ERROR(lastError, "SetupDiGetDevicePropertyW");
+ THROW_SETUPAPI_ERROR(lastError, "SetupDiGetDevicePropertyW");
}
}
@@ -190,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();
@@ -223,7 +225,7 @@ std::wstring GetDeviceInstanceId(
if (FALSE == status)
{
- THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetDeviceInstanceIdW");
+ THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiGetDeviceInstanceIdW");
}
return deviceInstanceId.data();
@@ -242,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);
@@ -288,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;
@@ -311,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;
@@ -334,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())
@@ -416,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;
@@ -440,7 +442,7 @@ void CreateTapDevice()
if (FALSE == status)
{
- THROW_WINDOWS_ERROR(GetLastError(), "SetupDiCreateDeviceInfoW");
+ THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiCreateDeviceInfoW");
}
status = SetupDiSetDeviceRegistryPropertyW(
@@ -453,7 +455,7 @@ void CreateTapDevice()
if (FALSE == status)
{
- THROW_WINDOWS_ERROR(GetLastError(), "SetupDiSetDeviceRegistryPropertyW");
+ THROW_SETUPAPI_ERROR(GetLastError(), "SetupDiSetDeviceRegistryPropertyW");
}
//
@@ -467,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");
@@ -503,7 +505,35 @@ ATTEMPT_UPDATE:
goto ATTEMPT_UPDATE;
}
- THROW_WINDOWS_ERROR(lastError, "UpdateDriverForPlugAndPlayDevicesW");
+ 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, "UpdateDriverForPlugAndPlayDevicesW");
}
//
@@ -745,6 +775,11 @@ int wmain(int argc, const wchar_t * argv[], const wchar_t * [])
goto INVALID_ARGUMENTS;
}
}
+ catch (const common::error::WindowsException &e)
+ {
+ LogError(common::string::ToWide(e.what()));
+ return e.errorCode();
+ }
catch (const std::exception &e)
{
LogError(common::string::ToWide(e.what()));
diff --git a/windows/driverlogic/src/error.cpp b/windows/driverlogic/src/error.cpp
new file mode 100644
index 0000000000..49909784ca
--- /dev/null
+++ b/windows/driverlogic/src/error.cpp
@@ -0,0 +1,165 @@
+#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 << ")"
+ << " (" << IsolateFilename(file) << ": " << line << ")";
+
+ throw common::error::WindowsException(ss.str().c_str(), code);
+ }
+
+ // 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__);\
+}
diff --git a/windows/driverlogic/src/stdafx.h b/windows/driverlogic/src/stdafx.h
index f3a07375c7..70def10da6 100644
--- a/windows/driverlogic/src/stdafx.h
+++ b/windows/driverlogic/src/stdafx.h
@@ -11,6 +11,11 @@
// Windows Header Files:
#include <windows.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <optional>
+
// TODO: reference additional headers your program requires here
diff --git a/windows/windows-libraries b/windows/windows-libraries
-Subproject ed2da7cb6b7ddf11b6f824258e842b91b453109
+Subproject c5abcd87bc057f2f0319a56037d1a9a721d6468