diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-11-03 12:27:42 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-11-03 12:27:42 +0100 |
commit | 7dede73406a970e910516ca9e5ea8a0f82945ae3 (patch) | |
tree | 6466c752da664bdc698d82c9d056d4aba725b52e /api/adapter.c | |
parent | api: move _L macro where it belongs (diff) | |
download | wintun-7dede73406a970e910516ca9e5ea8a0f82945ae3.tar.xz wintun-7dede73406a970e910516ca9e5ea8a0f82945ae3.zip |
api: add pool/driver removal for uninstaller semantics
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'api/adapter.c')
-rw-r--r-- | api/adapter.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/api/adapter.c b/api/adapter.c index 560f5f3..8cd244d 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -1750,12 +1750,18 @@ cleanupToken: } static WINTUN_STATUS -DeleteAllOurAdapters(void) +DeleteAllOurAdapters(_In_ WCHAR Pool[WINTUN_MAX_POOL], _Inout_ BOOL *RebootRequired) { + HANDLE Mutex = NamespaceTakePoolMutex(Pool); + if (!Mutex) + return ERROR_INVALID_HANDLE; DWORD Result = ERROR_SUCCESS; HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); if (DevInfo == INVALID_HANDLE_VALUE) + { + NamespaceReleaseMutex(Mutex); return LOG_LAST_ERROR(L"Failed to get present adapters"); + } SP_REMOVEDEVICE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER), .InstallFunction = DIF_REMOVE }, .Scope = DI_REMOVEDEVICE_GLOBAL }; @@ -1772,39 +1778,58 @@ DeleteAllOurAdapters(void) BOOL IsOurs; if (IsOurAdapter(DevInfo, &DevInfoData, &IsOurs) != ERROR_SUCCESS || !IsOurs) continue; + BOOL IsMember; + Result = IsPoolMember(Pool, DevInfo, &DevInfoData, &IsMember); + if (Result != ERROR_SUCCESS) + { + LOG(WINTUN_LOG_ERR, L"Failed to get pool membership"); + break; + } + if (!IsMember) + continue; LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter"); if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS) LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles"); LOG(WINTUN_LOG_INFO, L"Removing existing adapter"); - if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) || - !SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData)) + if (SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) && + SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData)) + *RebootRequired = *RebootRequired || CheckReboot(DevInfo, &DevInfoData); + else { LOG_LAST_ERROR(L"Failed to remove existing adapter"); Result = Result != ERROR_SUCCESS ? Result : GetLastError(); } } SetupDiDestroyDeviceInfoList(DevInfo); + NamespaceReleaseMutex(Mutex); return Result; } WINTUN_STATUS WINAPI -WintunDeleteDriver(void) +WintunDeletePoolDriver(_In_z_ WCHAR Pool[WINTUN_MAX_POOL], _Out_opt_ BOOL *RebootRequired) { if (!ElevateToSystem()) return LOG_LAST_ERROR(L"Failed to impersonate SYSTEM user"); - DWORD Result = ERROR_SUCCESS; + BOOL DummyRebootRequired; + if (!RebootRequired) + RebootRequired = &DummyRebootRequired; + *RebootRequired = FALSE; + DWORD Result; if (MAYBE_WOW64 && NativeMachine != IMAGE_FILE_PROCESS) { - Result = DeleteDriverViaRundll32(); + Result = DeletePoolDriverViaRundll32(Pool, RebootRequired); RevertToSelf(); return Result; } - /* DeleteAllOurAdapters(); */ + Result = DeleteAllOurAdapters(Pool, RebootRequired); + if (Result != ERROR_SUCCESS) + goto cleanupToken; + HANDLE DriverInstallationLock = NamespaceTakeDriverInstallationMutex(); if (!DriverInstallationLock) { @@ -1837,7 +1862,7 @@ WintunDeleteDriver(void) if (!_wcsicmp(DriverDetail->HardwareID, WINTUN_HWID)) { LOG(WINTUN_LOG_INFO, TEXT("Removing existing driver")); - if (!SetupUninstallOEMInfW(PathFindFileNameW(DriverDetail->InfFileName), SUOI_FORCEDELETE, NULL)) + if (!SetupUninstallOEMInfW(PathFindFileNameW(DriverDetail->InfFileName), 0, NULL)) { LOG_LAST_ERROR(TEXT("Unable to remove existing driver")); Result = Result != ERROR_SUCCESS ? Result : GetLastError(); |