diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-02-04 17:00:34 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2020-02-04 17:00:34 +0100 |
| commit | ef166a9f898eb9a98cc35d6b6dfb2fd410831892 (patch) | |
| tree | c95213f25501f63025e631a765c0d9722d221250 | |
| parent | 94849a26faa34223e61282d0b9595bd26c70c4e2 (diff) | |
| parent | 7f6e1ae579189756f4e9a133d93b938ed769efbf (diff) | |
| download | mullvadvpn-ef166a9f898eb9a98cc35d6b6dfb2fd410831892.tar.xz mullvadvpn-ef166a9f898eb9a98cc35d6b6dfb2fd410831892.zip | |
Merge branch 'driverlogic-update'
| m--------- | dist-assets/binaries | 0 | ||||
| -rw-r--r-- | dist-assets/windows/installer.nsh | 86 | ||||
| -rw-r--r-- | windows/driverlogic/src/driverlogic.cpp | 247 |
3 files changed, 150 insertions, 183 deletions
diff --git a/dist-assets/binaries b/dist-assets/binaries -Subproject 90a76633747020f346f07cf7b92e6470941ad00 +Subproject 90b0c06b59a0b9d6cda69924377335f39854b21 diff --git a/dist-assets/windows/installer.nsh b/dist-assets/windows/installer.nsh index d25ec9c58c..d44b0a7aae 100644 --- a/dist-assets/windows/installer.nsh +++ b/dist-assets/windows/installer.nsh @@ -27,14 +27,6 @@ # Return codes from driverlogic !define DL_GENERAL_ERROR 0 !define DL_GENERAL_SUCCESS 1 -!define DL_DELETE_NO_ADAPTERS_REMAIN 2 -!define DL_DELETE_SOME_ADAPTERS_REMAIN 3 - -# Return codes from tapinstall -!define DEVCON_EXIT_OK 0 -!define DEVCON_EXIT_REBOOT 1 -!define DEVCON_EXIT_FAIL 2 -!define DEVCON_EXIT_USAGE 3 # Log targets !define LOG_FILE 0 @@ -66,27 +58,27 @@ !define BreakInstallation '!insertmacro "BreakInstallation"' # -# ExtractDriver +# ExtractTapDriver # # Extract the correct driver for the current platform -# placing it into $TEMP\driver +# placing it into $TEMP\tap-driver # -!macro ExtractDriver +!macro ExtractTapDriver - SetOutPath "$TEMP\driver" + SetOutPath "$TEMP\tap-driver" File "${BUILD_RESOURCES_DIR}\..\windows\driverlogic\bin\x64-Release\driverlogic.exe" - File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\driver\*" + File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\tap-driver\*" ${If} ${AtLeastWin10} - File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\driver\win10\*" + File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\tap-driver\win10\*" ${Else} - File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\driver\win8\*" + File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\tap-driver\win8\*" ${EndIf} !macroend -!define ExtractDriver '!insertmacro "ExtractDriver"' +!define ExtractTapDriver '!insertmacro "ExtractTapDriver"' # # ExtractWintun @@ -171,7 +163,7 @@ Push $0 Push $1 - nsExec::ExecToStack '"$TEMP\driver\tapinstall.exe" remove ${TAP_HARDWARE_ID}' + nsExec::ExecToStack '"$TEMP\tap-driver\driverlogic.exe" remove ${TAP_HARDWARE_ID}' Pop $0 Pop $1 @@ -194,7 +186,7 @@ log::Log "RemoveVanillaTap()" - nsExec::ExecToStack '"$TEMP\driver\driverlogic.exe" remove-vanilla-tap' + nsExec::ExecToStack '"$TEMP\tap-driver\driverlogic.exe" remove-vanilla-tap' Pop $0 Pop $1 @@ -206,23 +198,6 @@ Goto RemoveVanillaTap_return ${EndIf} - ${If} $0 == ${DL_DELETE_NO_ADAPTERS_REMAIN} - log::Log "Removing vanilla TAP adapter driver since it is no longer in use" - - nsExec::ExecToStack '"$TEMP\driver\tapinstall.exe" remove ${DEPRECATED_TAP_HARDWARE_ID}' - - Pop $0 - Pop $1 - - ${If} $0 != ${DEVCON_EXIT_OK} - ${AndIf} $0 != ${DEVCON_EXIT_REBOOT} - StrCpy $R0 "Failed to remove driver: $1" - log::Log $R0 - - Goto RemoveVanillaTap_return - ${EndIf} - ${EndIf} - log::Log "RemoveVanillaTap() completed successfully" RemoveVanillaTap_return: @@ -238,17 +213,17 @@ !define RemoveVanillaTap '!insertmacro "RemoveVanillaTap"' # -# InstallDriver +# InstallTapDriver # -# Install tunnel driver or update it if already present on the system +# Install OpenVPN TAP adapter driver # # Returns: 0 in $R0 on success, otherwise an error message in $R0 # -!macro InstallDriver +!macro InstallTapDriver - Var /GLOBAL InstallDriver_TapName + Var /GLOBAL InstallTapDriver_TapName - log::Log "InstallDriver()" + log::Log "InstallTapDriver()" Push $0 Push $1 @@ -264,7 +239,7 @@ ${IfNot} ${AtLeastWin10} log::Log "Adding OpenVPN certificate to the certificate store" - nsExec::ExecToStack '"$SYSDIR\certutil.exe" -f -addstore TrustedPublisher "$TEMP\driver\driver.cer"' + nsExec::ExecToStack '"$SYSDIR\certutil.exe" -f -addstore TrustedPublisher "$TEMP\tap-driver\driver.cer"' Pop $0 Pop $1 @@ -275,20 +250,19 @@ ${EndIf} log::Log "Creating new virtual adapter" - nsExec::ExecToStack '"$TEMP\driver\driverlogic.exe" install "$TEMP\driver\OemVista.inf"' + nsExec::ExecToStack '"$TEMP\tap-driver\driverlogic.exe" install "$TEMP\tap-driver\OemVista.inf"' Pop $0 Pop $1 - ${If} $0 != ${DEVCON_EXIT_OK} - ${AndIf} $0 != ${DEVCON_EXIT_REBOOT} + ${If} $0 != ${DL_GENERAL_SUCCESS} StrCpy $R0 "Failed to create virtual adapter: error $0" log::LogWithDetails $R0 $1 - Goto InstallDriver_return + Goto InstallTapDriver_return ${EndIf} log::Log "Identifying recently added adapter" - nsExec::ExecToStack '"$TEMP\driver\driverlogic.exe" find-tap' + nsExec::ExecToStack '"$TEMP\tap-driver\driverlogic.exe" find-tap' Pop $0 Pop $1 @@ -296,10 +270,10 @@ ${If} $0 != ${DL_GENERAL_SUCCESS} StrCpy $R0 "Failed to identify new adapter: $1" log::Log $R0 - Goto InstallDriver_return + Goto InstallTapDriver_return ${EndIf} - StrCpy $InstallDriver_TapName $1 + StrCpy $InstallTapDriver_TapName $1 log::Log "New virtual adapter is named $\"$1$\"" log::Log "Renaming adapter to $\"Mullvad$\"" @@ -313,26 +287,26 @@ StrCpy $R0 "Failed to rename virtual adapter: error $0" log::LogWithDetails $R0 $1 - ${ForceRenameAdapter} $InstallDriver_TapName "Mullvad" + ${ForceRenameAdapter} $InstallTapDriver_TapName "Mullvad" ${If} $R0 != 0 - Goto InstallDriver_return + Goto InstallTapDriver_return ${EndIf} ${EndIf} - log::Log "InstallDriver() completed successfully" + log::Log "InstallTapDriver() completed successfully" Push 0 Pop $R0 - InstallDriver_return: + InstallTapDriver_return: Pop $1 Pop $0 !macroend -!define InstallDriver '!insertmacro "InstallDriver"' +!define InstallTapDriver '!insertmacro "InstallTapDriver"' # # RemoveWintun @@ -763,8 +737,8 @@ ${RemoveRelayCache} - ${ExtractDriver} - ${InstallDriver} + ${ExtractTapDriver} + ${InstallTapDriver} ${If} $R0 != 0 MessageBox MB_OK "Fatal error during driver installation: $R0" @@ -846,7 +820,7 @@ ${RemoveCLIFromEnvironPath} # Remove the TAP adapter - ${ExtractDriver} + ${ExtractTapDriver} ${RemoveBrandedTap} # If not ran silently diff --git a/windows/driverlogic/src/driverlogic.cpp b/windows/driverlogic/src/driverlogic.cpp index 16704b6c2b..e426cc2243 100644 --- a/windows/driverlogic/src/driverlogic.cpp +++ b/windows/driverlogic/src/driverlogic.cpp @@ -14,6 +14,7 @@ #include <devguid.h> #include <devpkey.h> #include <newdev.h> +#include <cfgmgr32.h> namespace @@ -26,9 +27,7 @@ constexpr wchar_t TAP_BASE_ALIAS[] = L"Mullvad"; enum ReturnCodes { GENERAL_ERROR, - GENERAL_SUCCESS, - DELETE_NO_ADAPTERS_REMAIN, - DELETE_SOME_ADAPTERS_REMAIN + GENERAL_SUCCESS }; struct NetworkAdapter @@ -69,7 +68,7 @@ void LogAdapters(const std::wstring &description, const std::set<NetworkAdapter> std::optional<std::wstring> GetDeviceRegistryStringProperty( HDEVINFO devInfo, - SP_DEVINFO_DATA *devInfoData, + const SP_DEVINFO_DATA &devInfoData, DWORD property ) { @@ -81,7 +80,7 @@ std::optional<std::wstring> GetDeviceRegistryStringProperty( const auto sizeStatus = SetupDiGetDeviceRegistryPropertyW( devInfo, - devInfoData, + const_cast<SP_DEVINFO_DATA*>(&devInfoData), property, nullptr, nullptr, @@ -110,7 +109,7 @@ std::optional<std::wstring> GetDeviceRegistryStringProperty( const auto status = SetupDiGetDeviceRegistryPropertyW( devInfo, - devInfoData, + const_cast<SP_DEVINFO_DATA*>(&devInfoData), property, nullptr, reinterpret_cast<PBYTE>(&buffer[0]), @@ -128,7 +127,7 @@ std::optional<std::wstring> GetDeviceRegistryStringProperty( std::wstring GetDeviceStringProperty( HDEVINFO devInfo, - SP_DEVINFO_DATA *devInfoData, + const SP_DEVINFO_DATA &devInfoData, const DEVPROPKEY *property ) { @@ -141,7 +140,7 @@ std::wstring GetDeviceStringProperty( const auto sizeStatus = SetupDiGetDevicePropertyW( devInfo, - devInfoData, + const_cast<SP_DEVINFO_DATA*>(&devInfoData), property, &type, nullptr, @@ -168,7 +167,7 @@ std::wstring GetDeviceStringProperty( const auto status = SetupDiGetDevicePropertyW( devInfo, - devInfoData, + const_cast<SP_DEVINFO_DATA*>(&devInfoData), property, &type, reinterpret_cast<PBYTE>(&buffer[0]), @@ -187,14 +186,14 @@ std::wstring GetDeviceStringProperty( std::wstring GetDeviceInstanceId( HDEVINFO devInfo, - SP_DEVINFO_DATA *devInfoData + const SP_DEVINFO_DATA &devInfoData ) { DWORD requiredSize = 0; SetupDiGetDeviceInstanceIdW( devInfo, - devInfoData, + const_cast<SP_DEVINFO_DATA*>(&devInfoData), nullptr, 0, &requiredSize @@ -204,7 +203,7 @@ std::wstring GetDeviceInstanceId( const auto status = SetupDiGetDeviceInstanceIdW( devInfo, - devInfoData, + const_cast<SP_DEVINFO_DATA *>(&devInfoData), &deviceInstanceId[0], requiredSize, nullptr @@ -257,11 +256,41 @@ std::wstring GetNetCfgInstanceId(HDEVINFO devInfo, const SP_DEVINFO_DATA &devInf return instanceId.data(); } -std::set<NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId) +bool DeleteDevice(HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { - std::set<NetworkAdapter> adapters; + const auto data = const_cast<SP_DEVINFO_DATA *>(&devInfoData); + + wchar_t devId[MAX_DEVICE_ID_LEN]; + if (CR_SUCCESS != CM_Get_Device_IDW(data->DevInst, devId, sizeof(devId) / sizeof(devId[0]), 0)) + { + // skip + return false; + } + + SP_REMOVEDEVICE_PARAMS rmdParams = { 0 }; + rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); + rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; + rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL; + rmdParams.HwProfile = 0; + + auto status = SetupDiSetClassInstallParamsW(devInfo, data, &rmdParams.ClassInstallHeader, sizeof(rmdParams)); + if (FALSE == status) + { + THROW_WINDOWS_ERROR(GetLastError(), "SetupDiSetClassInstallParamsW"); + } + + status = SetupDiCallClassInstaller(DIF_REMOVE, devInfo, data); + if (FALSE == status) + { + THROW_WINDOWS_ERROR(GetLastError(), "SetupDiCallClassInstaller"); + } - HDEVINFO devInfo = SetupDiGetClassDevs( + return true; +} + +void ForEachDevice(const std::wstring &tapHardwareId, std::function<void(HDEVINFO, const SP_DEVINFO_DATA &)> func) +{ + HDEVINFO devInfo = SetupDiGetClassDevsW( &GUID_DEVCLASS_NET, nullptr, nullptr, @@ -270,17 +299,15 @@ std::set<NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId) if (INVALID_HANDLE_VALUE == devInfo) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetClassDevs() failed"); + THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetClassDevsW"); } - common::memory::ScopeDestructor scopeDestructor; - scopeDestructor += [devInfo]() + common::memory::ScopeDestructor cleanupDevList; + cleanupDevList += [&devInfo]() { SetupDiDestroyDeviceInfoList(devInfo); }; - common::network::Nci nci; - for (int memberIndex = 0; ; memberIndex++) { SP_DEVINFO_DATA devInfoData = { 0 }; @@ -292,26 +319,45 @@ std::set<NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId) if (ERROR_NO_MORE_ITEMS == lastError) { - // Done break; } - THROW_WINDOWS_ERROR(lastError, "SetupDiEnumDeviceInfo() failed while enumerating network adapters"); + THROW_WINDOWS_ERROR(lastError, "Enumerating network adapters"); } try { - // - // Check whether this is a TAP adapter - // + const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, devInfoData, SPDRP_HARDWAREID); - const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, &devInfoData, SPDRP_HARDWAREID); - if (!hardwareId.has_value() - || wcscmp(hardwareId.value().c_str(), tapHardwareId.c_str()) != 0) + if (!hardwareId.has_value() || + 0 != tapHardwareId.compare(hardwareId.value())) { 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; + } + + func(devInfo, devInfoData); + } +} + +std::set<NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId) +{ + std::set<NetworkAdapter> adapters; + common::network::Nci nci; + + ForEachDevice(tapHardwareId, [&](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { + try + { // // Construct NetworkAdapter // @@ -321,21 +367,21 @@ std::set<NetworkAdapter> GetTapAdapters(const std::wstring &tapHardwareId) adapters.emplace(NetworkAdapter( guid, - GetDeviceStringProperty(devInfo, &devInfoData, &DEVPKEY_Device_DriverDesc), + GetDeviceStringProperty(devInfo, devInfoData, &DEVPKEY_Device_DriverDesc), nci.getConnectionName(guidObj), - GetDeviceInstanceId(devInfo, &devInfoData) + GetDeviceInstanceId(devInfo, devInfoData) )); } catch (const std::exception & e) { // - // Log exception and skip this adapter + // Skip this adapter // std::cerr << "Skipping TAP adapter due to exception caught while iterating: " << e.what() << std::endl; } - } + }); return adapters; } @@ -459,9 +505,9 @@ std::optional<NetworkAdapter> FindMullvadAdapter(const std::set<NetworkAdapter> auto findByAlias = [](const std::set<NetworkAdapter> &adapters, const std::wstring &alias) { const auto it = std::find_if(adapters.begin(), adapters.end(), [&alias](const NetworkAdapter &candidate) - { - return 0 == _wcsicmp(candidate.alias.c_str(), alias.c_str()); - }); + { + return 0 == _wcsicmp(candidate.alias.c_str(), alias.c_str()); + }); return it; }; @@ -514,13 +560,26 @@ NetworkAdapter FindBrandedTap() return *added.begin(); } -enum class DeletionResult +void RemoveTapDriver(const std::wstring &tapHardwareId) { - NO_REMAINING_TAP_ADAPTERS, - SOME_REMAINING_TAP_ADAPTERS -}; + ForEachDevice(tapHardwareId, [](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { + try + { + DeleteDevice(devInfo, devInfoData); + } + catch (const std::exception & e) + { + // + // Skip this adapter + // -DeletionResult DeleteVanillaMullvadAdapter() + std::cerr << "Skipping TAP adapter due to exception caught while iterating: " + << e.what() << std::endl; + } + }); +} + +void DeleteVanillaMullvadAdapter() { auto tapAdapters = GetTapAdapters(DEPRECATED_TAP_HARDWARE_ID); std::optional<NetworkAdapter> mullvadAdapter = FindMullvadAdapter(tapAdapters); @@ -531,98 +590,32 @@ DeletionResult DeleteVanillaMullvadAdapter() } const auto mullvadGuid = mullvadAdapter.value().guid; + bool deletedAdapter = false; - HDEVINFO devInfo = SetupDiGetClassDevsW( - &GUID_DEVCLASS_NET, - nullptr, - nullptr, - DIGCF_PRESENT - ); - - if (INVALID_HANDLE_VALUE == devInfo) - { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiGetClassDevsW() failed"); - } - - common::memory::ScopeDestructor cleanupDevList; - cleanupDevList += [&devInfo]() - { - SetupDiDestroyDeviceInfoList(devInfo); - }; - - int numRemainingAdapters = 0; - - for (int memberIndex = 0; ; memberIndex++) - { - SP_DEVINFO_DATA devInfoData = { 0 }; - devInfoData.cbSize = sizeof(devInfoData); - - if (FALSE == SetupDiEnumDeviceInfo(devInfo, memberIndex, &devInfoData)) - { - const auto lastError = GetLastError(); - - if (ERROR_NO_MORE_ITEMS == lastError) - { - break; - } - - THROW_WINDOWS_ERROR(lastError, "Error enumerating network adapters"); - } - + ForEachDevice(DEPRECATED_TAP_HARDWARE_ID, [&](HDEVINFO devInfo, const SP_DEVINFO_DATA &devInfoData) { try { - const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, &devInfoData, SPDRP_HARDWAREID); - - if (!hardwareId.has_value()) - { - continue; - } - if (0 != wcscmp(DEPRECATED_TAP_HARDWARE_ID, hardwareId.value().data())) - { - continue; - } - if (0 != GetNetCfgInstanceId(devInfo, devInfoData).compare(mullvadGuid)) - { - numRemainingAdapters++; - continue; - } - - // - // Delete existing device - // - - SP_REMOVEDEVICE_PARAMS rmdParams; - rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); - rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; - rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL; - rmdParams.HwProfile = 0; - - auto status = SetupDiSetClassInstallParamsW(devInfo, &devInfoData, &rmdParams.ClassInstallHeader, sizeof(rmdParams)); - if (FALSE == status) + if (0 == GetNetCfgInstanceId(devInfo, devInfoData).compare(mullvadGuid)) { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiSetClassInstallParamsW"); - } - - status = SetupDiCallClassInstaller(DIF_REMOVE, devInfo, &devInfoData); - if (FALSE == status) - { - THROW_WINDOWS_ERROR(GetLastError(), "SetupDiCallClassInstaller"); + deletedAdapter = DeleteDevice(devInfo, devInfoData) || deletedAdapter; } } catch (const std::exception & e) { // - // Log exception and skip this adapter + // Skip this adapter // std::cerr << "Skipping TAP adapter due to exception caught while iterating: " - << e.what(); + << e.what() << std::endl; + return; } - } + }); - return (numRemainingAdapters > 0) - ? DeletionResult::SOME_REMAINING_TAP_ADAPTERS - : DeletionResult::NO_REMAINING_TAP_ADAPTERS; + if (!deletedAdapter) + { + THROW_ERROR("TAP adapter was not removed"); + } } } // anonymous namespace @@ -655,18 +648,18 @@ int wmain(int argc, const wchar_t * argv[], const wchar_t * []) UpdateTapDriver(argv[2]); } - else if (0 == _wcsicmp(argv[1], L"remove-vanilla-tap")) + else if (0 == _wcsicmp(argv[1], L"remove")) { - switch (DeleteVanillaMullvadAdapter()) + if (3 != argc) { - case DeletionResult::NO_REMAINING_TAP_ADAPTERS: - std::wcout << L"Removed vanilla Mullvad TAP."; - return DELETE_NO_ADAPTERS_REMAIN; - - case DeletionResult::SOME_REMAINING_TAP_ADAPTERS: - std::wcout << L"Removed vanilla Mullvad TAP."; - return DELETE_SOME_ADAPTERS_REMAIN; + goto INVALID_ARGUMENTS; } + + RemoveTapDriver(argv[2]); + } + else if (0 == _wcsicmp(argv[1], L"remove-vanilla-tap")) + { + DeleteVanillaMullvadAdapter(); } else if (0 == _wcsicmp(argv[1], L"find-tap")) { |
