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>
This commit is contained in:
parent
1b3af95be3
commit
a332f54a1b
@ -214,9 +214,15 @@ ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevIn
|
|||||||
LOG(WINTUN_LOG_ERR, L"Failed to get adapter device object");
|
LOG(WINTUN_LOG_ERR, L"Failed to get adapter device object");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
Result = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL)
|
if (DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL))
|
||||||
? ERROR_SUCCESS
|
{
|
||||||
: LOG_LAST_ERROR(L"Failed to perform ioctl");
|
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);
|
CloseHandle(NdisHandle);
|
||||||
out:
|
out:
|
||||||
HeapFree(ModuleHeap, 0, InstanceId);
|
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");
|
LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter");
|
||||||
if (ForceCloseWintunAdapterHandle(DevInfo, &DeviceNode->Data) != ERROR_SUCCESS)
|
if (ForceCloseWintunAdapterHandle(DevInfo, &DeviceNode->Data) != ERROR_SUCCESS)
|
||||||
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
|
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
|
||||||
Sleep(200);
|
|
||||||
|
|
||||||
LOG(WINTUN_LOG_INFO, L"Disabling existing adapter");
|
LOG(WINTUN_LOG_INFO, L"Disabling existing adapter");
|
||||||
if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) ||
|
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");
|
LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter");
|
||||||
if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS)
|
if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS)
|
||||||
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
|
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
|
||||||
Sleep(200);
|
|
||||||
|
|
||||||
LOG(WINTUN_LOG_INFO, L"Removing existing adapter");
|
LOG(WINTUN_LOG_INFO, L"Removing existing adapter");
|
||||||
if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) ||
|
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");
|
LOG(WINTUN_LOG_ERR, L"Failed to get device info data");
|
||||||
goto cleanupToken;
|
goto cleanupToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS)
|
||||||
|
LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles");
|
||||||
|
|
||||||
SetQuietInstall(DevInfo, &DevInfoData);
|
SetQuietInstall(DevInfo, &DevInfoData);
|
||||||
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
|
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
|
||||||
.InstallFunction = DIF_REMOVE },
|
.InstallFunction = DIF_REMOVE },
|
||||||
|
10
wintun.c
10
wintun.c
@ -759,7 +759,7 @@ TunUnregisterBuffers(_Inout_ TUN_CTX *Ctx, _In_ FILE_OBJECT *Owner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||||
static VOID
|
static BOOLEAN
|
||||||
TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
|
TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
@ -769,6 +769,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
|
|||||||
ULONG VerifierFlags = 0;
|
ULONG VerifierFlags = 0;
|
||||||
OBJECT_HANDLE_INFORMATION HandleInfo;
|
OBJECT_HANDLE_INFORMATION HandleInfo;
|
||||||
SYSTEM_HANDLE_INFORMATION_EX *HandleTable = NULL;
|
SYSTEM_HANDLE_INFORMATION_EX *HandleTable = NULL;
|
||||||
|
BOOLEAN DidClose = FALSE;
|
||||||
|
|
||||||
MmIsVerifierEnabled(&VerifierFlags);
|
MmIsVerifierEnabled(&VerifierFlags);
|
||||||
|
|
||||||
@ -781,7 +782,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
|
|||||||
ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
|
ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
|
||||||
HandleTable = ExAllocatePoolWithTag(PagedPool, RequestedSize, TUN_MEMORY_TAG);
|
HandleTable = ExAllocatePoolWithTag(PagedPool, RequestedSize, TUN_MEMORY_TAG);
|
||||||
if (!HandleTable)
|
if (!HandleTable)
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status) || !HandleTable)
|
if (!NT_SUCCESS(Status) || !HandleTable)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -808,6 +809,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
|
|||||||
ObCloseHandle(HandleTable->Handles[Index].HandleValue, UserMode);
|
ObCloseHandle(HandleTable->Handles[Index].HandleValue, UserMode);
|
||||||
if (!VerifierFlags)
|
if (!VerifierFlags)
|
||||||
ObfDereferenceObject(Object);
|
ObfDereferenceObject(Object);
|
||||||
|
DidClose = TRUE;
|
||||||
}
|
}
|
||||||
KeUnstackDetachProcess(&ApcState);
|
KeUnstackDetachProcess(&ApcState);
|
||||||
ObfDereferenceObject(Process);
|
ObfDereferenceObject(Process);
|
||||||
@ -815,6 +817,7 @@ TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
|
|||||||
cleanup:
|
cleanup:
|
||||||
if (HandleTable)
|
if (HandleTable)
|
||||||
ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
|
ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
|
||||||
|
return DidClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS TunInitializeDispatchSecurityDescriptor(VOID)
|
static NTSTATUS TunInitializeDispatchSecurityDescriptor(VOID)
|
||||||
@ -927,8 +930,7 @@ TunDispatchDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TUN_IOCTL_FORCE_CLOSE_HANDLES:
|
case TUN_IOCTL_FORCE_CLOSE_HANDLES:
|
||||||
TunForceHandlesClosed(Stack->FileObject->DeviceObject);
|
Status = TunForceHandlesClosed(Stack->FileObject->DeviceObject) ? STATUS_SUCCESS : STATUS_NOTHING_TO_TERMINATE;
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Loading…
Reference in New Issue
Block a user