diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-10-30 14:21:13 +0100 |
---|---|---|
committer | Simon Rozman <simon@rozman.si> | 2020-10-31 19:11:49 +0100 |
commit | a332f54a1bfce683382228a3a66556a79abd613b (patch) | |
tree | fb87b920e475503ccb00d70e5194cf09834e5561 | |
parent | api: selectively use temporary variable to prepare output (diff) | |
download | wintun-a332f54a1bfce683382228a3a66556a79abd613b.tar.xz wintun-a332f54a1bfce683382228a3a66556a79abd613b.zip |
api: only sleep after force closing handles if required
Also force close handles when deleting the adapter, in case the function
is called from another process, for example an uninstaller.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | api/adapter.c | 18 | ||||
-rw-r--r-- | wintun.c | 10 |
2 files changed, 19 insertions, 9 deletions
diff --git a/api/adapter.c b/api/adapter.c index 459d155..741cec9 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -214,9 +214,15 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevIn LOG(WINTUN_LOG_ERR, L"Failed to get adapter device object"); goto out; } - Result = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL) - ? ERROR_SUCCESS - : LOG_LAST_ERROR(L"Failed to perform ioctl"); + if (DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL)) + { + Result = ERROR_SUCCESS; + Sleep(200); + } + else if (GetLastError() == ERROR_NOTHING_TO_TERMINATE) + Result = ERROR_SUCCESS; + else + Result = LOG_LAST_ERROR(L"Failed to perform ioctl"); CloseHandle(NdisHandle); out: HeapFree(ModuleHeap, 0, InstanceId); @@ -258,7 +264,6 @@ AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **Disa LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter"); if (ForceCloseWintunAdapterHandle(DevInfo, &DeviceNode->Data) != ERROR_SUCCESS) LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles"); - Sleep(200); LOG(WINTUN_LOG_INFO, L"Disabling existing adapter"); if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) || @@ -327,7 +332,6 @@ AdapterDeleteAllOurs(void) 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"); - Sleep(200); LOG(WINTUN_LOG_INFO, L"Removing existing adapter"); if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) || @@ -1717,6 +1721,10 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ LOG(WINTUN_LOG_ERR, L"Failed to get device info data"); goto cleanupToken; } + + if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS) + LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles"); + SetQuietInstall(DevInfo, &DevInfoData); SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER), .InstallFunction = DIF_REMOVE }, @@ -759,7 +759,7 @@ TunUnregisterBuffers(_Inout_ TUN_CTX *Ctx, _In_ FILE_OBJECT *Owner) } _IRQL_requires_max_(PASSIVE_LEVEL) -static VOID +static BOOLEAN TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject) { NTSTATUS Status; @@ -769,6 +769,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject) ULONG VerifierFlags = 0; OBJECT_HANDLE_INFORMATION HandleInfo; SYSTEM_HANDLE_INFORMATION_EX *HandleTable = NULL; + BOOLEAN DidClose = FALSE; MmIsVerifierEnabled(&VerifierFlags); @@ -781,7 +782,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject) ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG); HandleTable = ExAllocatePoolWithTag(PagedPool, RequestedSize, TUN_MEMORY_TAG); if (!HandleTable) - return; + return FALSE; } if (!NT_SUCCESS(Status) || !HandleTable) goto cleanup; @@ -808,6 +809,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject) ObCloseHandle(HandleTable->Handles[Index].HandleValue, UserMode); if (!VerifierFlags) ObfDereferenceObject(Object); + DidClose = TRUE; } KeUnstackDetachProcess(&ApcState); ObfDereferenceObject(Process); @@ -815,6 +817,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject) cleanup: if (HandleTable) ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG); + return DidClose; } static NTSTATUS TunInitializeDispatchSecurityDescriptor(VOID) @@ -927,8 +930,7 @@ TunDispatchDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp) break; } case TUN_IOCTL_FORCE_CLOSE_HANDLES: - TunForceHandlesClosed(Stack->FileObject->DeviceObject); - Status = STATUS_SUCCESS; + Status = TunForceHandlesClosed(Stack->FileObject->DeviceObject) ? STATUS_SUCCESS : STATUS_NOTHING_TO_TERMINATE; break; } cleanup: |