aboutsummaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2020-10-15 11:32:06 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2020-10-30 16:51:00 +0100
commit16a9737578c585db969be64b522777c18d2b1ad6 (patch)
treee52f5b04d7c92811a8987cccdc2a0a52363202ef /api
parentapi: simplify logger macros names (diff)
downloadwintun-16a9737578c585db969be64b522777c18d2b1ad6.tar.xz
wintun-16a9737578c585db969be64b522777c18d2b1ad6.zip
api: internal reorganization
Gather adapter management in adapter.h/.c (formerly devmgmt.h/.c) and unify HwID tests. Use "Namespace" namespace in all functions from namespace.h/.c. Fix char strings in LOG_... Signed-off-by: Simon Rozman <simon@rozman.si>
Diffstat (limited to 'api')
-rw-r--r--api/adapter.c (renamed from api/devmgmt.c)415
-rw-r--r--api/adapter.h (renamed from api/devmgmt.h)35
-rw-r--r--api/api.c4
-rw-r--r--api/api.vcxproj4
-rw-r--r--api/api.vcxproj.filters12
-rw-r--r--api/driver.c368
-rw-r--r--api/driver.h12
-rw-r--r--api/namespace.c4
-rw-r--r--api/namespace.h4
-rw-r--r--api/pch.h2
-rw-r--r--api/registry.c6
-rw-r--r--api/resource.c2
12 files changed, 424 insertions, 444 deletions
diff --git a/api/devmgmt.c b/api/adapter.c
index c57cdf1..319e3bc 100644
--- a/api/devmgmt.c
+++ b/api/adapter.c
@@ -11,6 +11,56 @@
static _locale_t Locale;
/**
+ * Retrieves driver information detail for a device information set or a particular device information element in the
+ * device information set.
+ *
+ * @param DevInfo A handle to the device information set that contains a device information element that
+ * represents the device for which to retrieve driver information.
+ *
+ * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
+ *
+ * @param DrvInfoData A pointer to a structure that specifies the driver information element that represents the
+ * driver for which to retrieve details.
+ *
+ * @param DrvInfoDetailData A pointer to a structure that receives detailed information about the specified driver.
+ * Must be released with HeapFree(GetProcessHeap(), 0, *DrvInfoDetailData) after use.
+ *
+ * @return ERROR_SUCCESS on success; Win32 error code otherwise.
+ */
+WINTUN_STATUS
+AdapterGetDrvInfoDetail(
+ _In_ HDEVINFO DevInfo,
+ _In_opt_ SP_DEVINFO_DATA *DevInfoData,
+ _In_ SP_DRVINFO_DATA_W *DrvInfoData,
+ _Out_ SP_DRVINFO_DETAIL_DATA_W **DrvInfoDetailData)
+{
+ HANDLE Heap = GetProcessHeap();
+ DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100;
+ DWORD Result;
+ for (;;)
+ {
+ *DrvInfoDetailData = HeapAlloc(Heap, 0, Size);
+ if (!*DrvInfoDetailData)
+ {
+ Result = ERROR_OUTOFMEMORY;
+ goto out;
+ }
+ (*DrvInfoDetailData)->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
+ if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DrvInfoData, *DrvInfoDetailData, Size, &Size))
+ return ERROR_SUCCESS;
+ Result = GetLastError();
+ HeapFree(Heap, 0, *DrvInfoDetailData);
+ if (Result != ERROR_INSUFFICIENT_BUFFER)
+ {
+ LOG_ERROR(L"Failed", Result);
+ goto out;
+ }
+ }
+out:
+ return Result;
+}
+
+/**
* Retrieves a specified Plug and Play device property.
*
* @param DevInfo A handle to the device information set that contains a device information element that
@@ -140,19 +190,273 @@ GetDeviceRegistryMultiString(
}
/**
- * Tests if any of the hardware IDs match ours.
+ * Tests if any of device compatible hardware IDs match ours.
*
- * @param Hwids Multi-string containing a list of hardware IDs.
+ * @param DevInfo A handle to the device information set that contains a device information element that
+ * represents the device.
+ *
+ * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
*
- * @return TRUE on match; FALSE otherwise.
+ * @return ERROR_SUCCESS on success; Win32 error code otherwise.
*/
-static BOOL
-IsOurHardwareID(_In_z_ WCHAR *Hwids)
+static WINTUN_STATUS
+IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOOL *IsOur)
{
- for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
- if (!_wcsicmp(Hwids, WINTUN_HWID))
- return TRUE;
- return FALSE;
+ WCHAR *Hwids;
+ DWORD Result = GetDeviceRegistryMultiString(DevInfo, DevInfoData, SPDRP_HARDWAREID, &Hwids);
+ if (Result != ERROR_SUCCESS)
+ return LOG_ERROR(L"Failed to query hardware ID", Result);
+ *IsOur = DriverIsOurHardwareID(Hwids);
+ return ERROR_SUCCESS;
+}
+
+/**
+ * Returns a handle to the adapter device object.
+ *
+ * @param InstanceId Adapter device instance ID.
+ *
+ * @param Handle Pointer to receive the adapter device object handle. Must be released with CloseHandle.
+ *
+ * @return ERROR_SUCCESS on success; Win32 error code otherwise.
+ */
+static WINTUN_STATUS
+GetDeviceObject(_In_opt_z_ const WCHAR *InstanceId, _Out_ HANDLE *Handle)
+{
+ HANDLE Heap = GetProcessHeap();
+ ULONG InterfacesLen;
+ DWORD Result = CM_Get_Device_Interface_List_SizeW(
+ &InterfacesLen, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
+ if (Result != CR_SUCCESS)
+ {
+ LOG(WINTUN_LOG_ERR, L"Failed to get device associated device instances size");
+ return ERROR_GEN_FAILURE;
+ }
+ WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR));
+ if (!Interfaces)
+ return ERROR_OUTOFMEMORY;
+ Result = CM_Get_Device_Interface_ListW(
+ (GUID *)&GUID_DEVINTERFACE_NET,
+ (DEVINSTID_W)InstanceId,
+ Interfaces,
+ InterfacesLen,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
+ if (Result != CR_SUCCESS)
+ {
+ LOG(WINTUN_LOG_ERR, L"Failed to get device associated device instances");
+ Result = ERROR_GEN_FAILURE;
+ goto cleanupBuf;
+ }
+ *Handle = CreateFileW(
+ Interfaces,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ Result = *Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : LOG_LAST_ERROR(L"Failed to connect to device");
+cleanupBuf:
+ HeapFree(Heap, 0, Interfaces);
+ return Result;
+}
+
+#define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
+
+/**
+ * Closes all client handles to the Wintun adapter.
+ *
+ * @param DevInfo A handle to the device information set that contains a device information element that
+ * represents the device.
+ *
+ * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
+ *
+ * @return ERROR_SUCCESS on success; Win32 error code otherwise.
+ */
+static WINTUN_STATUS
+ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
+{
+ DWORD Result = ERROR_SUCCESS;
+ DWORD RequiredBytes;
+ if (SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, NULL, 0, &RequiredBytes) ||
+ (Result = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
+ return LOG_ERROR(L"Failed to query device instance ID size", Result);
+ HANDLE Heap = GetProcessHeap();
+ WCHAR *InstanceId = HeapAlloc(Heap, HEAP_ZERO_MEMORY, sizeof(*InstanceId) * RequiredBytes);
+ if (!InstanceId)
+ return ERROR_OUTOFMEMORY;
+ if (!SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, InstanceId, RequiredBytes, &RequiredBytes))
+ {
+ Result = LOG_LAST_ERROR(L"Failed to get device instance ID");
+ goto out;
+ }
+ HANDLE NdisHandle;
+ Result = GetDeviceObject(InstanceId, &NdisHandle);
+ if (Result != ERROR_SUCCESS)
+ {
+ LOG_ERROR(L"Failed to get adapter device object", Result);
+ 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");
+ CloseHandle(NdisHandle);
+out:
+ HeapFree(Heap, 0, InstanceId);
+ return Result;
+}
+
+/**
+ * Disables all Wintun adapters.
+ *
+ * @param DevInfo A handle to the device information set.
+ *
+ * @param DisabledAdapters Output list of disabled adapters. The adapters disabled are inserted in the list head.
+ *
+ * @return ERROR_SUCCESS on success; Win32 error code otherwise.
+ */
+WINTUN_STATUS
+AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **DisabledAdapters)
+{
+ SP_PROPCHANGE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
+ .InstallFunction = DIF_PROPERTYCHANGE },
+ .StateChange = DICS_DISABLE,
+ .Scope = DICS_FLAG_GLOBAL };
+ DWORD Result = ERROR_SUCCESS;
+ HANDLE Heap = GetProcessHeap();
+ for (DWORD EnumIndex = 0;; ++EnumIndex)
+ {
+ SP_DEVINFO_DATA_LIST *DeviceNode = HeapAlloc(Heap, 0, sizeof(SP_DEVINFO_DATA_LIST));
+ if (!DeviceNode)
+ return ERROR_OUTOFMEMORY;
+ DeviceNode->Data.cbSize = sizeof(SP_DEVINFO_DATA);
+ if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DeviceNode->Data))
+ {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS)
+ {
+ HeapFree(Heap, 0, DeviceNode);
+ break;
+ }
+ goto cleanupDeviceInfoData;
+ }
+ BOOL IsOur;
+ if (IsOurAdapter(DevInfo, &DeviceNode->Data, &IsOur) != ERROR_SUCCESS || !IsOur)
+ goto cleanupDeviceInfoData;
+
+ ULONG Status, ProblemCode;
+ if (CM_Get_DevNode_Status(&Status, &ProblemCode, DeviceNode->Data.DevInst, 0) != CR_SUCCESS ||
+ ((Status & DN_HAS_PROBLEM) && ProblemCode == CM_PROB_DISABLED))
+ goto cleanupDeviceInfoData;
+
+ 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)) ||
+ !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data))
+ {
+ LOG_LAST_ERROR(L"Unable to disable existing adapter");
+ Result = Result != ERROR_SUCCESS ? Result : GetLastError();
+ goto cleanupDeviceInfoData;
+ }
+
+ DeviceNode->Next = *DisabledAdapters;
+ *DisabledAdapters = DeviceNode;
+ continue;
+
+ cleanupDeviceInfoData:
+ HeapFree(Heap, 0, &DeviceNode->Data);
+ }
+ return Result;
+}
+
+/**
+ * Enables all adapters.
+ *
+ * @param DevInfo A handle to the device information set.
+ *
+ * @param AdaptersToEnable Input list of adapters to enable.
+ *
+ * @return ERROR_SUCCESS on success; Win32 error code otherwise.
+ */
+WINTUN_STATUS
+AdapterEnableAll(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA_LIST *AdaptersToEnable)
+{
+ SP_PROPCHANGE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
+ .InstallFunction = DIF_PROPERTYCHANGE },
+ .StateChange = DICS_ENABLE,
+ .Scope = DICS_FLAG_GLOBAL };
+ DWORD Result = ERROR_SUCCESS;
+ for (SP_DEVINFO_DATA_LIST *DeviceNode = AdaptersToEnable; DeviceNode; DeviceNode = DeviceNode->Next)
+ {
+ LOG(WINTUN_LOG_INFO, L"Enabling existing adapter");
+ if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) ||
+ !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data))
+ {
+ LOG_LAST_ERROR(L"Unable to enable existing adapter");
+ Result = Result != ERROR_SUCCESS ? Result : GetLastError();
+ }
+ }
+ return Result;
+}
+
+/**
+ * Removes all Wintun adapters.
+ *
+ * @return ERROR_SUCCESS on success; Win32 error code otherwise.
+ */
+WINTUN_STATUS
+AdapterDeleteAllOurs()
+{
+ DWORD Result = ERROR_SUCCESS;
+ HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
+ if (DevInfo == INVALID_HANDLE_VALUE)
+ return LOG_LAST_ERROR(L"Failed to get present class devices");
+ SP_REMOVEDEVICE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
+ .InstallFunction = DIF_REMOVE },
+ .Scope = DI_REMOVEDEVICE_GLOBAL };
+ for (DWORD EnumIndex = 0;; ++EnumIndex)
+ {
+ SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
+ if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData))
+ {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ continue;
+ }
+
+ BOOL IsOur;
+ if (IsOurAdapter(DevInfo, &DevInfoData, &IsOur) != ERROR_SUCCESS || !IsOur)
+ 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");
+ Sleep(200);
+
+ LOG(WINTUN_LOG_INFO, L"Removing existing adapter");
+ if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) ||
+ !SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData))
+ {
+ LOG_LAST_ERROR(L"Unable to remove existing adapter");
+ Result = Result != ERROR_SUCCESS ? Result : GetLastError();
+ }
+ }
+ SetupDiDestroyDeviceInfoList(DevInfo);
+ return Result;
+}
+
+void
+AdapterInit()
+{
+ Locale = _wcreate_locale(LC_ALL, L"");
+}
+
+void
+AdapterCleanup()
+{
+ _free_locale(Locale);
}
/**
@@ -528,7 +832,7 @@ WintunGetAdapter(
_Out_ WINTUN_ADAPTER **Adapter)
{
DWORD Result;
- HANDLE Mutex = TakeNameMutex(Pool);
+ HANDLE Mutex = NamespaceTakeMutex(Pool);
if (!Mutex)
return ERROR_INVALID_HANDLE;
@@ -539,7 +843,6 @@ WintunGetAdapter(
goto cleanupMutex;
}
- HANDLE Heap = GetProcessHeap();
for (DWORD EnumIndex = 0;; ++EnumIndex)
{
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
@@ -566,25 +869,17 @@ WintunGetAdapter(
continue;
}
- /* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
- * devices. */
- WCHAR *Hwids;
- Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
+ /* Check the Hardware ID to make sure it's a real Wintun device. */
+ BOOL IsOur;
+ Result = IsOurAdapter(DevInfo, &DevInfoData, &IsOur);
if (Result != ERROR_SUCCESS)
{
- LOG_ERROR(L"Failed to query hardware ID", Result);
- goto cleanupDevInfo;
- }
- if (!IsOurHardwareID(Hwids))
- {
- HeapFree(Heap, 0, Hwids);
- Result = ERROR_ALREADY_EXISTS;
+ LOG_ERROR(L"Failed to determine hardware ID", Result);
goto cleanupDevInfo;
}
- HeapFree(Heap, 0, Hwids);
-
- if (!DriverIsWintunAdapter(DevInfo, &DevInfoData))
+ if (!IsOur)
{
+ LOG_ERROR(L"Foreign adapter with the same name exists", Result);
Result = ERROR_ALREADY_EXISTS;
goto cleanupDevInfo;
}
@@ -598,6 +893,7 @@ WintunGetAdapter(
}
if (!IsMember)
{
+ LOG_ERROR(L"Wintun adapter with the same name exists in another pool", Result);
Result = ERROR_ALREADY_EXISTS;
goto cleanupDevInfo;
}
@@ -612,7 +908,7 @@ WintunGetAdapter(
cleanupDevInfo:
SetupDiDestroyDeviceInfoList(DevInfo);
cleanupMutex:
- ReleaseNameMutex(Mutex);
+ NamespaceReleaseMutex(Mutex);
return Result;
}
@@ -739,8 +1035,7 @@ WintunGetAdapterLUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ LUID *Luid)
WINTUN_STATUS WINAPI
WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle)
{
- *Handle = DriverGetAdapterDeviceObject(Adapter->DevInstanceID);
- return *Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : GetLastError();
+ return GetDeviceObject(Adapter->DevInstanceID, Handle);
}
/**
@@ -797,7 +1092,7 @@ WintunCreateAdapter(
_Inout_ BOOL *RebootRequired)
{
DWORD Result;
- HANDLE Mutex = TakeNameMutex(Pool);
+ HANDLE Mutex = NamespaceTakeMutex(Pool);
if (!Mutex)
return ERROR_INVALID_HANDLE;
@@ -862,12 +1157,10 @@ WintunCreateAdapter(
if (!IsNewer(&DrvInfoData, &DriverDate, DriverVersion))
continue;
- SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, &DevInfoData, &DrvInfoData);
- if (!DrvInfoDetailData)
+ SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData;
+ if (AdapterGetDrvInfoDetail(DevInfo, &DevInfoData, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS)
continue;
- if ((DrvInfoDetailData->CompatIDsOffset <= 1 || _wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID)) &&
- (!DrvInfoDetailData->CompatIDsLength ||
- !IsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset)))
+ if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData))
{
HeapFree(Heap, 0, DrvInfoDetailData);
continue;
@@ -1021,7 +1314,7 @@ WintunCreateAdapter(
goto cleanupTcpipAdapterRegKey;
}
- const static DWORD EnableDeadGWDetect = 0;
+ static const DWORD EnableDeadGWDetect = 0;
Result = RegSetKeyValueW(
TcpipInterfaceRegKey, NULL, L"EnableDeadGWDetect", REG_DWORD, &EnableDeadGWDetect, sizeof(EnableDeadGWDetect));
if (Result != ERROR_SUCCESS)
@@ -1055,7 +1348,7 @@ cleanupDriverInfoList:
cleanupDevInfo:
SetupDiDestroyDeviceInfoList(DevInfo);
cleanupMutex:
- ReleaseNameMutex(Mutex);
+ NamespaceReleaseMutex(Mutex);
return Result;
}
@@ -1111,10 +1404,10 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
WINTUN_STATUS WINAPI
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param)
{
- DWORD Result;
- HANDLE Mutex = TakeNameMutex(Pool);
+ HANDLE Mutex = NamespaceTakeMutex(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)
{
@@ -1122,36 +1415,25 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_
goto cleanupMutex;
}
HANDLE Heap = GetProcessHeap();
- for (DWORD EnumIndex = 0;; ++EnumIndex)
+ BOOL Continue = TRUE;
+ for (DWORD EnumIndex = 0; Continue; ++EnumIndex)
{
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData))
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
- {
- Result = ERROR_SUCCESS;
break;
- }
continue;
}
- /* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
- * devices. */
- WCHAR *Hwids;
- Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
+ BOOL IsOur;
+ Result = IsOurAdapter(DevInfo, &DevInfoData, &IsOur);
if (Result != ERROR_SUCCESS)
{
- LOG_ERROR(L"Failed to query hardware ID", Result);
+ LOG_ERROR(L"Failed to determine hardware ID", Result);
break;
}
- if (!IsOurHardwareID(Hwids))
- {
- HeapFree(Heap, 0, Hwids);
- continue;
- }
- HeapFree(Heap, 0, Hwids);
-
- if (!DriverIsWintunAdapter(DevInfo, &DevInfoData))
+ if (!IsOur)
continue;
BOOL IsMember;
@@ -1171,28 +1453,11 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_
LOG_ERROR(L"Failed to create adapter data", Result);
break;
}
- if (Func(Adapter, Param))
- HeapFree(Heap, 0, Adapter);
- else
- {
- HeapFree(Heap, 0, Adapter);
- break;
- }
+ Continue = Func(Adapter, Param);
+ HeapFree(Heap, 0, Adapter);
}
SetupDiDestroyDeviceInfoList(DevInfo);
cleanupMutex:
- ReleaseNameMutex(Mutex);
+ NamespaceReleaseMutex(Mutex);
return Result;
}
-
-void
-DevmgmtInit()
-{
- Locale = _wcreate_locale(LC_ALL, L"");
-}
-
-void
-DevmgmtCleanup()
-{
- _free_locale(Locale);
-}
diff --git a/api/devmgmt.h b/api/adapter.h
index 48dced5..5f38e46 100644
--- a/api/devmgmt.h
+++ b/api/adapter.h
@@ -6,11 +6,40 @@
#pragma once
#include "api.h"
+#include <SetupAPI.h>
#include <IPExport.h>
#define MAX_POOL 256
#define MAX_INSTANCE_ID MAX_PATH /* TODO: Is MAX_PATH always enough? */
+typedef struct _SP_DEVINFO_DATA_LIST
+{
+ SP_DEVINFO_DATA Data;
+ struct _SP_DEVINFO_DATA_LIST *Next;
+} SP_DEVINFO_DATA_LIST;
+
+WINTUN_STATUS
+AdapterGetDrvInfoDetail(
+ _In_ HDEVINFO DevInfo,
+ _In_opt_ SP_DEVINFO_DATA *DevInfoData,
+ _In_ SP_DRVINFO_DATA_W *DrvInfoData,
+ _Out_ SP_DRVINFO_DETAIL_DATA_W **DrvInfoDetailData);
+
+WINTUN_STATUS
+AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **DisabledAdapters);
+
+WINTUN_STATUS
+AdapterEnableAll(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA_LIST *AdaptersToEnable);
+
+WINTUN_STATUS
+AdapterDeleteAllOurs();
+
+void
+AdapterInit();
+
+void
+AdapterCleanup();
+
typedef struct _WINTUN_ADAPTER
{
GUID CfgInstanceID;
@@ -59,9 +88,3 @@ typedef BOOL(CALLBACK *WINTUN_ENUM_FUNC)(_In_ const WINTUN_ADAPTER *Adapter, _In
WINTUN_STATUS WINAPI
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param);
-
-void
-DevmgmtInit();
-
-void
-DevmgmtCleanup();
diff --git a/api/api.c b/api/api.c
index a470e04..adb2c13 100644
--- a/api/api.c
+++ b/api/api.c
@@ -67,15 +67,15 @@ DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved)
{
case DLL_PROCESS_ATTACH:
ResourceModule = hinstDLL;
+ AdapterInit();
NamespaceInit();
NciInit();
- DevmgmtInit();
break;
case DLL_PROCESS_DETACH:
- DevmgmtCleanup();
NciCleanup();
NamespaceCleanup();
+ AdapterCleanup();
break;
}
return TRUE;
diff --git a/api/api.vcxproj b/api/api.vcxproj
index e405f0e..b65726f 100644
--- a/api/api.vcxproj
+++ b/api/api.vcxproj
@@ -190,7 +190,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="api.h" />
- <ClInclude Include="devmgmt.h" />
+ <ClInclude Include="adapter.h" />
<ClInclude Include="driver.h" />
<ClInclude Include="logger.h" />
<ClInclude Include="namespace.h" />
@@ -201,7 +201,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="api.c" />
- <ClCompile Include="devmgmt.c" />
+ <ClCompile Include="adapter.c" />
<ClCompile Include="driver.c" />
<ClCompile Include="logger.c" />
<ClCompile Include="namespace.c" />
diff --git a/api/api.vcxproj.filters b/api/api.vcxproj.filters
index 188ad86..b64b00b 100644
--- a/api/api.vcxproj.filters
+++ b/api/api.vcxproj.filters
@@ -40,9 +40,6 @@
<ClInclude Include="registry.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="devmgmt.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="logger.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -52,6 +49,9 @@
<ClInclude Include="driver.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="adapter.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="api.c">
@@ -60,9 +60,6 @@
<ClCompile Include="namespace.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="devmgmt.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="nci.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -84,5 +81,8 @@
<ClCompile Include="driver.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="adapter.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/api/driver.c b/api/driver.c
index 3a27f0a..60d9a25 100644
--- a/api/driver.c
+++ b/api/driver.c
@@ -7,153 +7,35 @@
#pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */
-typedef struct _SP_DEVINFO_DATA_LIST
-{
- SP_DEVINFO_DATA Data;
- struct _SP_DEVINFO_DATA_LIST *Next;
-} SP_DEVINFO_DATA_LIST;
-
/**
- * Retrieves driver information detail for a device information set or a particular device information element in the
- * device information set.
- *
- * @param DevInfo A handle to the device information set that contains a device information element that
- * represents the device for which to retrieve driver information.
- *
- * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
- *
- * @param DrvInfoData A pointer to a structure that specifies the driver information element that represents the
- * driver for which to retrieve details.
+ * Tests if any of the hardware IDs match ours.
*
- * @param DrvInfoDetailData A pointer to a structure that receives detailed information about the specified driver.
- * Must be released with HeapFree(GetProcessHeap(), 0, *DrvInfoDetailData) after use.
+ * @param Hwids Multi-string containing a list of hardware IDs.
*
- * @return non-zero on success; zero otherwise - use GetLastError().
- */
-_Return_type_success_(return != NULL) SP_DRVINFO_DETAIL_DATA_W *DriverGetDrvInfoDetail(
- _In_ HDEVINFO DevInfo,
- _In_opt_ SP_DEVINFO_DATA *DevInfoData,
- _In_ SP_DRVINFO_DATA_W *DrvInfoData)
-{
- HANDLE Heap = GetProcessHeap();
- DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100;
- DWORD Result;
- for (;;)
- {
- SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = HeapAlloc(Heap, 0, Size);
- if (!DrvInfoDetailData)
- {
- Result = ERROR_OUTOFMEMORY;
- goto out;
- }
- DrvInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
- if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DrvInfoData, DrvInfoDetailData, Size, &Size))
- return DrvInfoDetailData;
- Result = GetLastError();
- HeapFree(Heap, 0, DrvInfoDetailData);
- if (Result != ERROR_INSUFFICIENT_BUFFER)
- {
- LOG_ERROR(L"Failed", Result);
- goto out;
- }
- }
-out:
- SetLastError(Result);
- return NULL;
-}
-
-/**
- * Checks if the device (i.e. network adapter) is using Wintun driver.
- *
- * @param DevInfo A handle to the device information set that contains a device information element that
- * represents the device.
- *
- * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
- *
- * @return non-zero when using Wintun driver; zero when not or error - use GetLastError().
+ * @return TRUE on match; FALSE otherwise.
*/
BOOL
-DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData)
+DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids)
{
- BOOL Found = FALSE;
- if (!SetupDiBuildDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER))
- {
- LOG_LAST_ERROR(L"Failed to build list of drivers");
- return FALSE;
- }
- HANDLE Heap = GetProcessHeap();
- for (DWORD EnumIndex = 0; !Found; ++EnumIndex)
- {
- SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(SP_DRVINFO_DATA_W) };
- if (!SetupDiEnumDriverInfoW(DevInfo, DevInfoData, SPDIT_COMPATDRIVER, EnumIndex, &DrvInfoData))
- {
- if (GetLastError() == ERROR_NO_MORE_ITEMS)
- break;
- continue;
- }
- SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, DevInfoData, &DrvInfoData);
- if (!DrvInfoDetailData)
- continue;
- Found = !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID);
- HeapFree(Heap, 0, DrvInfoDetailData);
- }
- SetupDiDestroyDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER);
- SetLastError(ERROR_SUCCESS);
- return Found;
+ for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
+ if (!_wcsicmp(Hwids, WINTUN_HWID))
+ return TRUE;
+ return FALSE;
}
/**
- * Returns a handle to the adapter device object.
+ * Tests if hardware ID or any of the compatible IDs match ours.
*
- * @param InstanceId Adapter device instance ID.
+ * @param DrvInfoDetailData Detailed information about a particular driver information structure.
*
- * @return device handle on success; INVALID_HANDLE_VALUE otherwise - use GetLastError().
+ * @return TRUE on match; FALSE otherwise.
*/
-_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE
- DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId)
+BOOL
+DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData)
{
- HANDLE Heap = GetProcessHeap();
- ULONG InterfacesLen;
- HANDLE Handle = INVALID_HANDLE_VALUE;
- DWORD Result = CM_Get_Device_Interface_List_SizeW(
- &InterfacesLen, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
- if (Result != CR_SUCCESS)
- {
- LOG(WINTUN_LOG_ERR, L"Failed to get device associated device instances size");
- SetLastError(ERROR_GEN_FAILURE);
- return INVALID_HANDLE_VALUE;
- }
- WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR));
- if (!Interfaces)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- return INVALID_HANDLE_VALUE;
- }
- Result = CM_Get_Device_Interface_ListW(
- (GUID *)&GUID_DEVINTERFACE_NET,
- (DEVINSTID_W)InstanceId,
- Interfaces,
- InterfacesLen,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
- if (Result != CR_SUCCESS)
- {
- LOG(WINTUN_LOG_ERR, L"Failed to get device associated device instances");
- Result = ERROR_GEN_FAILURE;
- goto cleanupBuf;
- }
- Handle = CreateFileW(
- Interfaces,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- Result = Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : LOG_LAST_ERROR(L"Failed to connect to device");
-cleanupBuf:
- HeapFree(Heap, 0, Interfaces);
- SetLastError(Result);
- return Handle;
+ return DrvInfoDetailData->CompatIDsOffset > 1 && !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID) ||
+ DrvInfoDetailData->CompatIDsLength &&
+ DriverIsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset);
}
#if defined(HAVE_EV) || defined(HAVE_WHQL)
@@ -405,7 +287,7 @@ InstallCertificate(_In_z_ const WCHAR *SignedResource)
DWORD SizeResource;
DWORD Result = ResourceGetAddress(SignedResource, &LockedResource, &SizeResource);
if (Result != ERROR_SUCCESS)
- return LOG_ERROR("Failed to locate resource", Result);
+ return LOG_ERROR(L"Failed to locate resource", Result);
const CERT_BLOB CertBlob = { .cbData = SizeResource, .pbData = (BYTE *)LockedResource };
HCERTSTORE QueriedStore;
if (!CryptQueryObject(
@@ -420,7 +302,7 @@ InstallCertificate(_In_z_ const WCHAR *SignedResource)
&QueriedStore,
0,
NULL))
- return LOG_LAST_ERROR("Failed to find certificate");
+ return LOG_LAST_ERROR(L"Failed to find certificate");
HCERTSTORE TrustedStore =
CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"TrustedPublisher");
if (!TrustedStore)
@@ -576,207 +458,26 @@ static WINTUN_STATUS RemoveDriver(VOID)
break;
continue;
}
- SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData);
- if (!DrvInfoDetailData)
+ SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData;
+ if (AdapterGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS)
continue;
- if (!_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID))
- {
- PathStripPathW(DrvInfoDetailData->InfFileName);
- LOG(WINTUN_LOG_INFO, L"Removing existing driver");
- if (!SetupUninstallOEMInfW(DrvInfoDetailData->InfFileName, SUOI_FORCEDELETE, NULL))
- {
- LOG_LAST_ERROR(L"Unable to remove existing driver");
- Result = Result != ERROR_SUCCESS ? Result : GetLastError();
- }
- }
- HeapFree(Heap, 0, DrvInfoDetailData);
- }
- SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER);
-cleanupDeviceInfoSet:
- SetupDiDestroyDeviceInfoList(DevInfo);
- return Result;
-}
-
-# define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
-
-/**
- * Closes all client handles to the Wintun adapter.
- *
- * @param DevInfo A handle to the device information set that contains a device information element that
- * represents the device.
- *
- * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
- *
- * @return ERROR_SUCCESS on success; Win32 error code otherwise.
- */
-static WINTUN_STATUS
-ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
-{
- DWORD Result = ERROR_SUCCESS;
- DWORD RequiredBytes;
- if (SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, NULL, 0, &RequiredBytes) ||
- (Result = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
- return LOG_ERROR(L"Failed to query device instance ID size", Result);
- HANDLE Heap = GetProcessHeap();
- WCHAR *InstanceId = HeapAlloc(Heap, HEAP_ZERO_MEMORY, sizeof(*InstanceId) * RequiredBytes);
- if (!InstanceId)
- return ERROR_OUTOFMEMORY;
- if (!SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, InstanceId, RequiredBytes, &RequiredBytes))
- {
- Result = LOG_LAST_ERROR(L"Failed to get device instance ID");
- goto out;
- }
- HANDLE NdisHandle = DriverGetAdapterDeviceObject(InstanceId);
- if (NdisHandle == INVALID_HANDLE_VALUE)
- {
- Result = GetLastError();
- 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");
- CloseHandle(NdisHandle);
-out:
- HeapFree(Heap, 0, InstanceId);
- return Result;
-}
-
-/**
- * Disables Wintun adapters.
- *
- * @param DevInfo A handle to the device information set.
- *
- * @param DisabledAdapters Output list of disabled adapters. The adapters disabled are inserted in the list head.
- *
- * @return ERROR_SUCCESS on success; Win32 error code otherwise.
- */
-static WINTUN_STATUS
-DisableWintunAdapters(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **DisabledAdapters)
-{
- SP_PROPCHANGE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
- .InstallFunction = DIF_PROPERTYCHANGE },
- .StateChange = DICS_DISABLE,
- .Scope = DICS_FLAG_GLOBAL };
- DWORD Result = ERROR_SUCCESS;
- HANDLE Heap = GetProcessHeap();
- for (DWORD EnumIndex = 0;; ++EnumIndex)
- {
- SP_DEVINFO_DATA_LIST *DeviceNode = HeapAlloc(Heap, 0, sizeof(SP_DEVINFO_DATA_LIST));
- if (!DeviceNode)
- return ERROR_OUTOFMEMORY;
- DeviceNode->Data.cbSize = sizeof(SP_DEVINFO_DATA);
- if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DeviceNode->Data))
- {
- if (GetLastError() == ERROR_NO_MORE_ITEMS)
- {
- HeapFree(Heap, 0, DeviceNode);
- break;
- }
- goto cleanupDeviceInfoData;
- }
- if (!DriverIsWintunAdapter(DevInfo, &DeviceNode->Data))
- goto cleanupDeviceInfoData;
-
- ULONG Status, ProblemCode;
- if (CM_Get_DevNode_Status(&Status, &ProblemCode, DeviceNode->Data.DevInst, 0) != CR_SUCCESS ||
- ((Status & DN_HAS_PROBLEM) && ProblemCode == CM_PROB_DISABLED))
- goto cleanupDeviceInfoData;
-
- 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)) ||
- !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data))
- {
- LOG_LAST_ERROR(L"Unable to disable existing adapter");
- Result = Result != ERROR_SUCCESS ? Result : GetLastError();
- goto cleanupDeviceInfoData;
- }
-
- DeviceNode->Next = *DisabledAdapters;
- *DisabledAdapters = DeviceNode;
- continue;
-
- cleanupDeviceInfoData:
- HeapFree(Heap, 0, &DeviceNode->Data);
- }
- return Result;
-}
-
-/**
- * Removes all Wintun adapters.
- *
- * @param DevInfo A handle to the device information set.
- *
- * @param DisabledAdapters Output list of disabled adapters.
- *
- * @return ERROR_SUCCESS on success; Win32 error code otherwise.
- */
-static WINTUN_STATUS
-RemoveWintunAdapters(_In_ HDEVINFO DevInfo)
-{
- SP_REMOVEDEVICE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
- .InstallFunction = DIF_REMOVE },
- .Scope = DI_REMOVEDEVICE_GLOBAL };
- DWORD Result = ERROR_SUCCESS;
- for (DWORD EnumIndex = 0;; ++EnumIndex)
- {
- SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
- if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData))
+ if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData))
{
- if (GetLastError() == ERROR_NO_MORE_ITEMS)
- break;
+ HeapFree(Heap, 0, DrvInfoDetailData);
continue;
}
- if (!DriverIsWintunAdapter(DevInfo, &DevInfoData))
- 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");
- Sleep(200);
-
- LOG(WINTUN_LOG_INFO, L"Removing existing adapter");
- if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) ||
- !SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData))
+ PathStripPathW(DrvInfoDetailData->InfFileName);
+ LOG(WINTUN_LOG_INFO, L"Removing existing driver");
+ if (!SetupUninstallOEMInfW(DrvInfoDetailData->InfFileName, SUOI_FORCEDELETE, NULL))
{
- LOG_LAST_ERROR(L"Unable to remove existing adapter");
- Result = Result != ERROR_SUCCESS ? Result : GetLastError();
- }
- }
- return Result;
-}
-
-/**
- * Enables Wintun adapters.
- *
- * @param DevInfo A handle to the device information set.
- *
- * @param AdaptersToEnable Input list of adapters to enable.
- *
- * @return ERROR_SUCCESS on success; Win32 error code otherwise.
- */
-static WINTUN_STATUS
-EnableWintunAdapters(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA_LIST *AdaptersToEnable)
-{
- SP_PROPCHANGE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
- .InstallFunction = DIF_PROPERTYCHANGE },
- .StateChange = DICS_ENABLE,
- .Scope = DICS_FLAG_GLOBAL };
- DWORD Result = ERROR_SUCCESS;
- for (SP_DEVINFO_DATA_LIST *DeviceNode = AdaptersToEnable; DeviceNode; DeviceNode = DeviceNode->Next)
- {
- LOG(WINTUN_LOG_INFO, L"Enabling existing adapter");
- if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) ||
- !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data))
- {
- LOG_LAST_ERROR(L"Unable to enable existing adapter");
+ LOG_LAST_ERROR(L"Unable to remove existing driver");
Result = Result != ERROR_SUCCESS ? Result : GetLastError();
}
+ HeapFree(Heap, 0, DrvInfoDetailData);
}
+ SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER);
+cleanupDeviceInfoSet:
+ SetupDiDestroyDeviceInfoList(DevInfo);
return Result;
}
@@ -794,7 +495,7 @@ WINTUN_STATUS DriverInstallOrUpdate(VOID)
SP_DEVINFO_DATA_LIST *ExistingAdapters = NULL;
if (IsDriverLoaded())
{
- DisableWintunAdapters(DevInfo, &ExistingAdapters);
+ AdapterDisableAllOurs(DevInfo, &ExistingAdapters);
LOG(WINTUN_LOG_INFO, L"Waiting for driver to unload from kernel");
if (!EnsureDriverUnloaded())
LOG(WINTUN_LOG_WARN, L"Unable to unload driver, which means a reboot will likely be required");
@@ -815,7 +516,7 @@ WINTUN_STATUS DriverInstallOrUpdate(VOID)
cleanupAdapters:;
if (ExistingAdapters)
{
- EnableWintunAdapters(DevInfo, ExistingAdapters);
+ AdapterEnableAll(DevInfo, ExistingAdapters);
while (ExistingAdapters)
{
SP_DEVINFO_DATA_LIST *Next = ExistingAdapters->Next;
@@ -834,10 +535,7 @@ cleanupAdapters:;
*/
WINTUN_STATUS DriverUninstall(VOID)
{
- HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
- if (DevInfo == INVALID_HANDLE_VALUE)
- return LOG_LAST_ERROR(L"Failed to get present class devices");
- RemoveWintunAdapters(DevInfo);
+ AdapterDeleteAllOurs();
DWORD Result = RemoveDriver();
if (Result != ERROR_SUCCESS)
LOG_ERROR(L"Failed to uninstall driver", Result);
diff --git a/api/driver.h b/api/driver.h
index 3f91025..d7906b3 100644
--- a/api/driver.h
+++ b/api/driver.h
@@ -7,20 +7,14 @@
#include "api.h"
#include <Windows.h>
-#include <SetupAPI.h>
#define WINTUN_HWID L"Wintun"
-_Return_type_success_(return != NULL) SP_DRVINFO_DETAIL_DATA_W *DriverGetDrvInfoDetail(
- _In_ HDEVINFO DevInfo,
- _In_opt_ SP_DEVINFO_DATA *DevInfoData,
- _In_ SP_DRVINFO_DATA_W *DrvInfoData);
-
BOOL
-DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData);
+DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids);
-_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE
- DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId);
+BOOL
+DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData);
#if defined(HAVE_EV) || defined(HAVE_WHQL)
diff --git a/api/namespace.c b/api/namespace.c
index c69d5b7..91410b2 100644
--- a/api/namespace.c
+++ b/api/namespace.c
@@ -122,7 +122,7 @@ cleanupLeaveCriticalSection:
_Check_return_
HANDLE
-TakeNameMutex(_In_z_ const WCHAR *Pool)
+NamespaceTakeMutex(_In_z_ const WCHAR *Pool)
{
HANDLE Mutex = NULL;
@@ -171,7 +171,7 @@ cleanupSha256:
}
void
-ReleaseNameMutex(_In_ HANDLE Mutex)
+NamespaceReleaseMutex(_In_ HANDLE Mutex)
{
ReleaseMutex(Mutex);
CloseHandle(Mutex);
diff --git a/api/namespace.h b/api/namespace.h
index b5e77a9..8a26c4b 100644
--- a/api/namespace.h
+++ b/api/namespace.h
@@ -9,10 +9,10 @@
_Check_return_
HANDLE
-TakeNameMutex(_In_z_ const WCHAR *Pool);
+NamespaceTakeMutex(_In_z_ const WCHAR *Pool);
void
-ReleaseNameMutex(_In_ HANDLE Mutex);
+NamespaceReleaseMutex(_In_ HANDLE Mutex);
void
NamespaceInit();
diff --git a/api/pch.h b/api/pch.h
index 5af7fbd..d2da7f8 100644
--- a/api/pch.h
+++ b/api/pch.h
@@ -5,8 +5,8 @@
#pragma once
+#include "adapter.h"
#include "api.h"
-#include "devmgmt.h"
#include "driver.h"
#include "logger.h"
#include "namespace.h"
diff --git a/api/registry.c b/api/registry.c
index e591a46..f735d4d 100644
--- a/api/registry.c
+++ b/api/registry.c
@@ -49,7 +49,7 @@ OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGL
TimeLeft = 0;
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
{
- LOG(WINTUN_LOG_ERR, "Timeout waiting");
+ LOG(WINTUN_LOG_ERR, L"Timeout waiting");
break;
}
}
@@ -349,7 +349,7 @@ RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD
TimeLeft = 0;
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
{
- LOG(WINTUN_LOG_ERR, "Timeout waiting");
+ LOG(WINTUN_LOG_ERR, L"Timeout waiting");
break;
}
}
@@ -427,7 +427,7 @@ RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD T
TimeLeft = 0;
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
{
- LOG(WINTUN_LOG_ERR, "Timeout waiting");
+ LOG(WINTUN_LOG_ERR, L"Timeout waiting");
break;
}
}
diff --git a/api/resource.c b/api/resource.c
index b59911e..7b1ea59 100644
--- a/api/resource.c
+++ b/api/resource.c
@@ -58,7 +58,7 @@ ResourceCopyToFile(
DWORD SizeResource;
DWORD Result = ResourceGetAddress(ResourceName, &LockedResource, &SizeResource);
if (Result != ERROR_SUCCESS)
- return LOG_ERROR("Failed to locate resource", Result);
+ return LOG_ERROR(L"Failed to locate resource", Result);
HANDLE DestinationHandle = CreateFileW(
DestinationPath,
GENERIC_WRITE,