diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-02-13 10:57:54 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2020-02-13 10:57:54 +0100 |
| commit | b7c2a1d6c6d14846591a30625bf3b05d069ca637 (patch) | |
| tree | 189d2154031620fc8524a64bad9cd959079e1e07 /windows/driverlogic/src/driverlogic.cpp | |
| parent | 6ab2a7767bc3e8ed63f436e93ec8b2eda5205752 (diff) | |
| parent | 3368555bd0b81f13c7419860915bd06c40505df9 (diff) | |
| download | mullvadvpn-b7c2a1d6c6d14846591a30625bf3b05d069ca637.tar.xz mullvadvpn-b7c2a1d6c6d14846591a30625bf3b05d069ca637.zip | |
Merge branch 'driverlogic-update'
Diffstat (limited to 'windows/driverlogic/src/driverlogic.cpp')
| -rw-r--r-- | windows/driverlogic/src/driverlogic.cpp | 128 |
1 files changed, 91 insertions, 37 deletions
diff --git a/windows/driverlogic/src/driverlogic.cpp b/windows/driverlogic/src/driverlogic.cpp index e426cc2243..f57ffc209b 100644 --- a/windows/driverlogic/src/driverlogic.cpp +++ b/windows/driverlogic/src/driverlogic.cpp @@ -15,6 +15,8 @@ #include <devpkey.h> #include <newdev.h> #include <cfgmgr32.h> +#include <io.h> +#include <fcntl.h> namespace @@ -288,7 +290,7 @@ bool DeleteDevice(HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) return true; } -void ForEachDevice(const std::wstring &tapHardwareId, std::function<void(HDEVINFO, const SP_DEVINFO_DATA &)> func) +void ForEachNetworkDevice(const std::optional<std::wstring> hwId, std::function<bool(HDEVINFO, const SP_DEVINFO_DATA &)> func) { HDEVINFO devInfo = SetupDiGetClassDevsW( &GUID_DEVCLASS_NET, @@ -325,37 +327,43 @@ void ForEachDevice(const std::wstring &tapHardwareId, std::function<void(HDEVINF THROW_WINDOWS_ERROR(lastError, "Enumerating network adapters"); } - try + if (hwId.has_value()) { - const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, devInfoData, SPDRP_HARDWAREID); + try + { + const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, devInfoData, SPDRP_HARDWAREID); - if (!hardwareId.has_value() || - 0 != tapHardwareId.compare(hardwareId.value())) + if (!hardwareId.has_value() || + 0 != hwId->compare(hardwareId.value())) + { + continue; + } + } + catch (const std::exception & e) { + // + // Skip this adapter + // + + std::wcerr << L"Skipping TAP adapter due to exception caught while iterating: " + << common::string::ToWide(e.what()) << std::endl; continue; } } - catch (const std::exception & e) - { - // - // Skip this adapter - // - std::cerr << "Skipping TAP adapter due to exception caught while iterating: " - << e.what() << std::endl; - continue; + if (!func(devInfo, devInfoData)) + { + break; } - - func(devInfo, devInfoData); } } -std::set<NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId) +std::set<NetworkAdapter> GetNetworkAdapters(const std::optional<std::wstring> hardwareId) { std::set<NetworkAdapter> adapters; common::network::Nci nci; - ForEachDevice(tapHardwareId, [&](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { + ForEachNetworkDevice(hardwareId, [&](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { try { // @@ -378,9 +386,10 @@ std::set<NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId) // Skip this adapter // - std::cerr << "Skipping TAP adapter due to exception caught while iterating: " - << e.what() << std::endl; + std::wcerr << L"Skipping adapter due to exception caught while iterating: " + << common::string::ToWide(e.what()) << std::endl; } + return true; }); return adapters; @@ -491,6 +500,42 @@ ATTEMPT_UPDATE: << rebootRequired; } +// +// Broken adapters may use our "Mullvad" name, so find one that is not in use. +// NOTE: Enumerating adapters first and picking the next free name is not sufficient, +// because the broken TAP may not be included. +// +void RenameAdapterToMullvad(const NetworkAdapter &adapter) +{ + common::network::Nci nci; + + try + { + nci.setConnectionName(common::Guid::FromString(adapter.guid), TAP_BASE_ALIAS); + return; + } + catch (...) + { + } + + for (int i = 1; i < 10; i++) + { + std::wstringstream ss; + ss << TAP_BASE_ALIAS << L"-" << i; + + try + { + nci.setConnectionName(common::Guid::FromString(adapter.guid), ss.str().c_str()); + return; + } + catch (...) + { + } + } + + THROW_ERROR("Exhausted TAP adapter namespace"); +} + std::optional<NetworkAdapter> FindMullvadAdapter(const std::set<NetworkAdapter> &tapAdapters) { if (tapAdapters.empty()) @@ -523,7 +568,7 @@ std::optional<NetworkAdapter> FindMullvadAdapter(const std::set<NetworkAdapter> // Look for TAP adapter with alias "Mullvad-1", "Mullvad-2", etc. // - for (auto i = 0; i < 10; ++i) + for (auto i = 1; i < 10; ++i) { std::wstringstream ss; @@ -544,7 +589,7 @@ std::optional<NetworkAdapter> FindMullvadAdapter(const std::set<NetworkAdapter> NetworkAdapter FindBrandedTap() { - std::set<NetworkAdapter> added = GetTapAdapters(TAP_HARDWARE_ID); + std::set<NetworkAdapter> added = GetNetworkAdapters(TAP_HARDWARE_ID); if (added.empty()) { @@ -562,7 +607,7 @@ NetworkAdapter FindBrandedTap() void RemoveTapDriver(const std::wstring &tapHardwareId) { - ForEachDevice(tapHardwareId, [](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { + ForEachNetworkDevice(tapHardwareId, [](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { try { DeleteDevice(devInfo, devInfoData); @@ -573,31 +618,38 @@ void RemoveTapDriver(const std::wstring &tapHardwareId) // Skip this adapter // - std::cerr << "Skipping TAP adapter due to exception caught while iterating: " - << e.what() << std::endl; + std::wcerr << L"Skipping TAP adapter due to exception caught while iterating: " + << common::string::ToWide(e.what()) << std::endl; } + return true; }); } void DeleteVanillaMullvadAdapter() { - auto tapAdapters = GetTapAdapters(DEPRECATED_TAP_HARDWARE_ID); + auto tapAdapters = GetNetworkAdapters(DEPRECATED_TAP_HARDWARE_ID); std::optional<NetworkAdapter> mullvadAdapter = FindMullvadAdapter(tapAdapters); if (!mullvadAdapter.has_value()) { - THROW_ERROR("Mullvad TAP adapter not found"); + return; } const auto mullvadGuid = mullvadAdapter.value().guid; bool deletedAdapter = false; - ForEachDevice(DEPRECATED_TAP_HARDWARE_ID, [&](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { + // + // Enumerate over all network devices with the hardware ID DEPRECATED_TAP_HARDWARE_ID, + // and delete any adapter whose GUID matches that of the "Mullvad" adapter. + // + + ForEachNetworkDevice(DEPRECATED_TAP_HARDWARE_ID, [&](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { try { if (0 == GetNetCfgInstanceId(devInfo, devInfoData).compare(mullvadGuid)) { - deletedAdapter = DeleteDevice(devInfo, devInfoData) || deletedAdapter; + deletedAdapter = DeleteDevice(devInfo, devInfoData); + return false; } } catch (const std::exception & e) @@ -606,10 +658,10 @@ void DeleteVanillaMullvadAdapter() // Skip this adapter // - std::cerr << "Skipping TAP adapter due to exception caught while iterating: " - << e.what() << std::endl; - return; + std::wcerr << L"Skipping TAP adapter due to exception caught while iterating: " + << common::string::ToWide(e.what()) << std::endl; } + return true; }); if (!deletedAdapter) @@ -622,6 +674,12 @@ void DeleteVanillaMullvadAdapter() int wmain(int argc, const wchar_t * argv[], const wchar_t * []) { + if (-1 == _setmode(_fileno(stdout), _O_U16TEXT) + || -1 == _setmode(_fileno(stderr), _O_U16TEXT)) + { + std::wcerr << L"Failed to set translation mode" << std::endl; + } + if (2 > argc) { goto INVALID_ARGUMENTS; @@ -638,6 +696,7 @@ int wmain(int argc, const wchar_t * argv[], const wchar_t * []) CreateTapDevice(); UpdateTapDriver(argv[2]); + RenameAdapterToMullvad(FindBrandedTap()); } else if (0 == _wcsicmp(argv[1], L"update")) { @@ -661,11 +720,6 @@ int wmain(int argc, const wchar_t * argv[], const wchar_t * []) { DeleteVanillaMullvadAdapter(); } - else if (0 == _wcsicmp(argv[1], L"find-tap")) - { - const auto tap = FindBrandedTap(); - std::wcout << tap.alias; - } else { goto INVALID_ARGUMENTS; @@ -673,7 +727,7 @@ int wmain(int argc, const wchar_t * argv[], const wchar_t * []) } catch (const std::exception &e) { - std::cerr << e.what(); + std::wcerr << common::string::ToWide(e.what()); return GENERAL_ERROR; } catch (...) |
