aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-10-30 14:21:13 +0100
committerSimon Rozman <simon@rozman.si>2020-10-31 19:11:49 +0100
commita332f54a1bfce683382228a3a66556a79abd613b (patch)
treefb87b920e475503ccb00d70e5194cf09834e5561
parentapi: selectively use temporary variable to prepare output (diff)
downloadwintun-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.c18
-rw-r--r--wintun.c10
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 },
diff --git a/wintun.c b/wintun.c
index 60eb9dd..55d6963 100644
--- a/wintun.c
+++ b/wintun.c
@@ -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: