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>
This commit is contained in:
parent
78b7a01eb3
commit
16a9737578
@ -10,6 +10,56 @@
|
|||||||
|
|
||||||
static _locale_t Locale;
|
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.
|
* Retrieves a specified Plug and Play device property.
|
||||||
*
|
*
|
||||||
@ -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.
|
||||||
*
|
*
|
||||||
* @return TRUE on match; FALSE otherwise.
|
* @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 BOOL
|
static WINTUN_STATUS
|
||||||
IsOurHardwareID(_In_z_ WCHAR *Hwids)
|
IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOOL *IsOur)
|
||||||
{
|
{
|
||||||
for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
|
WCHAR *Hwids;
|
||||||
if (!_wcsicmp(Hwids, WINTUN_HWID))
|
DWORD Result = GetDeviceRegistryMultiString(DevInfo, DevInfoData, SPDRP_HARDWAREID, &Hwids);
|
||||||
return TRUE;
|
if (Result != ERROR_SUCCESS)
|
||||||
return FALSE;
|
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)
|
_Out_ WINTUN_ADAPTER **Adapter)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
HANDLE Mutex = TakeNameMutex(Pool);
|
HANDLE Mutex = NamespaceTakeMutex(Pool);
|
||||||
if (!Mutex)
|
if (!Mutex)
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
@ -539,7 +843,6 @@ WintunGetAdapter(
|
|||||||
goto cleanupMutex;
|
goto cleanupMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE Heap = GetProcessHeap();
|
|
||||||
for (DWORD EnumIndex = 0;; ++EnumIndex)
|
for (DWORD EnumIndex = 0;; ++EnumIndex)
|
||||||
{
|
{
|
||||||
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
||||||
@ -566,25 +869,17 @@ WintunGetAdapter(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
|
/* Check the Hardware ID to make sure it's a real Wintun device. */
|
||||||
* devices. */
|
BOOL IsOur;
|
||||||
WCHAR *Hwids;
|
Result = IsOurAdapter(DevInfo, &DevInfoData, &IsOur);
|
||||||
Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
LOG_ERROR(L"Failed to query hardware ID", Result);
|
LOG_ERROR(L"Failed to determine hardware ID", Result);
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
if (!IsOurHardwareID(Hwids))
|
if (!IsOur)
|
||||||
{
|
|
||||||
HeapFree(Heap, 0, Hwids);
|
|
||||||
Result = ERROR_ALREADY_EXISTS;
|
|
||||||
goto cleanupDevInfo;
|
|
||||||
}
|
|
||||||
HeapFree(Heap, 0, Hwids);
|
|
||||||
|
|
||||||
if (!DriverIsWintunAdapter(DevInfo, &DevInfoData))
|
|
||||||
{
|
{
|
||||||
|
LOG_ERROR(L"Foreign adapter with the same name exists", Result);
|
||||||
Result = ERROR_ALREADY_EXISTS;
|
Result = ERROR_ALREADY_EXISTS;
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
@ -598,6 +893,7 @@ WintunGetAdapter(
|
|||||||
}
|
}
|
||||||
if (!IsMember)
|
if (!IsMember)
|
||||||
{
|
{
|
||||||
|
LOG_ERROR(L"Wintun adapter with the same name exists in another pool", Result);
|
||||||
Result = ERROR_ALREADY_EXISTS;
|
Result = ERROR_ALREADY_EXISTS;
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
@ -612,7 +908,7 @@ WintunGetAdapter(
|
|||||||
cleanupDevInfo:
|
cleanupDevInfo:
|
||||||
SetupDiDestroyDeviceInfoList(DevInfo);
|
SetupDiDestroyDeviceInfoList(DevInfo);
|
||||||
cleanupMutex:
|
cleanupMutex:
|
||||||
ReleaseNameMutex(Mutex);
|
NamespaceReleaseMutex(Mutex);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,8 +1035,7 @@ WintunGetAdapterLUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ LUID *Luid)
|
|||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle)
|
WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle)
|
||||||
{
|
{
|
||||||
*Handle = DriverGetAdapterDeviceObject(Adapter->DevInstanceID);
|
return GetDeviceObject(Adapter->DevInstanceID, Handle);
|
||||||
return *Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : GetLastError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -797,7 +1092,7 @@ WintunCreateAdapter(
|
|||||||
_Inout_ BOOL *RebootRequired)
|
_Inout_ BOOL *RebootRequired)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
HANDLE Mutex = TakeNameMutex(Pool);
|
HANDLE Mutex = NamespaceTakeMutex(Pool);
|
||||||
if (!Mutex)
|
if (!Mutex)
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
@ -862,12 +1157,10 @@ WintunCreateAdapter(
|
|||||||
if (!IsNewer(&DrvInfoData, &DriverDate, DriverVersion))
|
if (!IsNewer(&DrvInfoData, &DriverDate, DriverVersion))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, &DevInfoData, &DrvInfoData);
|
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData;
|
||||||
if (!DrvInfoDetailData)
|
if (AdapterGetDrvInfoDetail(DevInfo, &DevInfoData, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS)
|
||||||
continue;
|
continue;
|
||||||
if ((DrvInfoDetailData->CompatIDsOffset <= 1 || _wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID)) &&
|
if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData))
|
||||||
(!DrvInfoDetailData->CompatIDsLength ||
|
|
||||||
!IsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset)))
|
|
||||||
{
|
{
|
||||||
HeapFree(Heap, 0, DrvInfoDetailData);
|
HeapFree(Heap, 0, DrvInfoDetailData);
|
||||||
continue;
|
continue;
|
||||||
@ -1021,7 +1314,7 @@ WintunCreateAdapter(
|
|||||||
goto cleanupTcpipAdapterRegKey;
|
goto cleanupTcpipAdapterRegKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static DWORD EnableDeadGWDetect = 0;
|
static const DWORD EnableDeadGWDetect = 0;
|
||||||
Result = RegSetKeyValueW(
|
Result = RegSetKeyValueW(
|
||||||
TcpipInterfaceRegKey, NULL, L"EnableDeadGWDetect", REG_DWORD, &EnableDeadGWDetect, sizeof(EnableDeadGWDetect));
|
TcpipInterfaceRegKey, NULL, L"EnableDeadGWDetect", REG_DWORD, &EnableDeadGWDetect, sizeof(EnableDeadGWDetect));
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
@ -1055,7 +1348,7 @@ cleanupDriverInfoList:
|
|||||||
cleanupDevInfo:
|
cleanupDevInfo:
|
||||||
SetupDiDestroyDeviceInfoList(DevInfo);
|
SetupDiDestroyDeviceInfoList(DevInfo);
|
||||||
cleanupMutex:
|
cleanupMutex:
|
||||||
ReleaseNameMutex(Mutex);
|
NamespaceReleaseMutex(Mutex);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1111,10 +1404,10 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
|
|||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param)
|
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
HANDLE Mutex = NamespaceTakeMutex(Pool);
|
||||||
HANDLE Mutex = TakeNameMutex(Pool);
|
|
||||||
if (!Mutex)
|
if (!Mutex)
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
DWORD Result = ERROR_SUCCESS;
|
||||||
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
||||||
if (DevInfo == INVALID_HANDLE_VALUE)
|
if (DevInfo == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
@ -1122,36 +1415,25 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_
|
|||||||
goto cleanupMutex;
|
goto cleanupMutex;
|
||||||
}
|
}
|
||||||
HANDLE Heap = GetProcessHeap();
|
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) };
|
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
||||||
if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData))
|
if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData))
|
||||||
{
|
{
|
||||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||||
{
|
|
||||||
Result = ERROR_SUCCESS;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
|
BOOL IsOur;
|
||||||
* devices. */
|
Result = IsOurAdapter(DevInfo, &DevInfoData, &IsOur);
|
||||||
WCHAR *Hwids;
|
|
||||||
Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
LOG_ERROR(L"Failed to query hardware ID", Result);
|
LOG_ERROR(L"Failed to determine hardware ID", Result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!IsOurHardwareID(Hwids))
|
if (!IsOur)
|
||||||
{
|
|
||||||
HeapFree(Heap, 0, Hwids);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
HeapFree(Heap, 0, Hwids);
|
|
||||||
|
|
||||||
if (!DriverIsWintunAdapter(DevInfo, &DevInfoData))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BOOL IsMember;
|
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);
|
LOG_ERROR(L"Failed to create adapter data", Result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Func(Adapter, Param))
|
Continue = Func(Adapter, Param);
|
||||||
HeapFree(Heap, 0, Adapter);
|
HeapFree(Heap, 0, Adapter);
|
||||||
else
|
|
||||||
{
|
|
||||||
HeapFree(Heap, 0, Adapter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SetupDiDestroyDeviceInfoList(DevInfo);
|
SetupDiDestroyDeviceInfoList(DevInfo);
|
||||||
cleanupMutex:
|
cleanupMutex:
|
||||||
ReleaseNameMutex(Mutex);
|
NamespaceReleaseMutex(Mutex);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
DevmgmtInit()
|
|
||||||
{
|
|
||||||
Locale = _wcreate_locale(LC_ALL, L"");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DevmgmtCleanup()
|
|
||||||
{
|
|
||||||
_free_locale(Locale);
|
|
||||||
}
|
|
@ -6,11 +6,40 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
#include <SetupAPI.h>
|
||||||
#include <IPExport.h>
|
#include <IPExport.h>
|
||||||
|
|
||||||
#define MAX_POOL 256
|
#define MAX_POOL 256
|
||||||
#define MAX_INSTANCE_ID MAX_PATH /* TODO: Is MAX_PATH always enough? */
|
#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
|
typedef struct _WINTUN_ADAPTER
|
||||||
{
|
{
|
||||||
GUID CfgInstanceID;
|
GUID CfgInstanceID;
|
||||||
@ -59,9 +88,3 @@ typedef BOOL(CALLBACK *WINTUN_ENUM_FUNC)(_In_ const WINTUN_ADAPTER *Adapter, _In
|
|||||||
|
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param);
|
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param);
|
||||||
|
|
||||||
void
|
|
||||||
DevmgmtInit();
|
|
||||||
|
|
||||||
void
|
|
||||||
DevmgmtCleanup();
|
|
@ -67,15 +67,15 @@ DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved)
|
|||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
ResourceModule = hinstDLL;
|
ResourceModule = hinstDLL;
|
||||||
|
AdapterInit();
|
||||||
NamespaceInit();
|
NamespaceInit();
|
||||||
NciInit();
|
NciInit();
|
||||||
DevmgmtInit();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
DevmgmtCleanup();
|
|
||||||
NciCleanup();
|
NciCleanup();
|
||||||
NamespaceCleanup();
|
NamespaceCleanup();
|
||||||
|
AdapterCleanup();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -190,7 +190,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="api.h" />
|
<ClInclude Include="api.h" />
|
||||||
<ClInclude Include="devmgmt.h" />
|
<ClInclude Include="adapter.h" />
|
||||||
<ClInclude Include="driver.h" />
|
<ClInclude Include="driver.h" />
|
||||||
<ClInclude Include="logger.h" />
|
<ClInclude Include="logger.h" />
|
||||||
<ClInclude Include="namespace.h" />
|
<ClInclude Include="namespace.h" />
|
||||||
@ -201,7 +201,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="api.c" />
|
<ClCompile Include="api.c" />
|
||||||
<ClCompile Include="devmgmt.c" />
|
<ClCompile Include="adapter.c" />
|
||||||
<ClCompile Include="driver.c" />
|
<ClCompile Include="driver.c" />
|
||||||
<ClCompile Include="logger.c" />
|
<ClCompile Include="logger.c" />
|
||||||
<ClCompile Include="namespace.c" />
|
<ClCompile Include="namespace.c" />
|
||||||
|
@ -40,9 +40,6 @@
|
|||||||
<ClInclude Include="registry.h">
|
<ClInclude Include="registry.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="devmgmt.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="logger.h">
|
<ClInclude Include="logger.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -52,6 +49,9 @@
|
|||||||
<ClInclude Include="driver.h">
|
<ClInclude Include="driver.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="adapter.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="api.c">
|
<ClCompile Include="api.c">
|
||||||
@ -60,9 +60,6 @@
|
|||||||
<ClCompile Include="namespace.c">
|
<ClCompile Include="namespace.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="devmgmt.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="nci.c">
|
<ClCompile Include="nci.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -84,5 +81,8 @@
|
|||||||
<ClCompile Include="driver.c">
|
<ClCompile Include="driver.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="adapter.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
368
api/driver.c
368
api/driver.c
@ -7,153 +7,35 @@
|
|||||||
|
|
||||||
#pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */
|
#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
|
* Tests if any of the hardware IDs match ours.
|
||||||
* device information set.
|
|
||||||
*
|
*
|
||||||
* @param DevInfo A handle to the device information set that contains a device information element that
|
* @param Hwids Multi-string containing a list of hardware IDs.
|
||||||
* represents the device for which to retrieve driver information.
|
|
||||||
*
|
*
|
||||||
* @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
|
* @return TRUE on match; FALSE otherwise.
|
||||||
*
|
|
||||||
* @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 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().
|
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData)
|
DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids)
|
||||||
{
|
{
|
||||||
BOOL Found = FALSE;
|
for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
|
||||||
if (!SetupDiBuildDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER))
|
if (!_wcsicmp(Hwids, WINTUN_HWID))
|
||||||
{
|
return TRUE;
|
||||||
LOG_LAST_ERROR(L"Failed to build list of drivers");
|
return FALSE;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
BOOL
|
||||||
DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId)
|
DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData)
|
||||||
{
|
{
|
||||||
HANDLE Heap = GetProcessHeap();
|
return DrvInfoDetailData->CompatIDsOffset > 1 && !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID) ||
|
||||||
ULONG InterfacesLen;
|
DrvInfoDetailData->CompatIDsLength &&
|
||||||
HANDLE Handle = INVALID_HANDLE_VALUE;
|
DriverIsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_EV) || defined(HAVE_WHQL)
|
#if defined(HAVE_EV) || defined(HAVE_WHQL)
|
||||||
@ -405,7 +287,7 @@ InstallCertificate(_In_z_ const WCHAR *SignedResource)
|
|||||||
DWORD SizeResource;
|
DWORD SizeResource;
|
||||||
DWORD Result = ResourceGetAddress(SignedResource, &LockedResource, &SizeResource);
|
DWORD Result = ResourceGetAddress(SignedResource, &LockedResource, &SizeResource);
|
||||||
if (Result != ERROR_SUCCESS)
|
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 };
|
const CERT_BLOB CertBlob = { .cbData = SizeResource, .pbData = (BYTE *)LockedResource };
|
||||||
HCERTSTORE QueriedStore;
|
HCERTSTORE QueriedStore;
|
||||||
if (!CryptQueryObject(
|
if (!CryptQueryObject(
|
||||||
@ -420,7 +302,7 @@ InstallCertificate(_In_z_ const WCHAR *SignedResource)
|
|||||||
&QueriedStore,
|
&QueriedStore,
|
||||||
0,
|
0,
|
||||||
NULL))
|
NULL))
|
||||||
return LOG_LAST_ERROR("Failed to find certificate");
|
return LOG_LAST_ERROR(L"Failed to find certificate");
|
||||||
HCERTSTORE TrustedStore =
|
HCERTSTORE TrustedStore =
|
||||||
CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"TrustedPublisher");
|
CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"TrustedPublisher");
|
||||||
if (!TrustedStore)
|
if (!TrustedStore)
|
||||||
@ -576,18 +458,20 @@ static WINTUN_STATUS RemoveDriver(VOID)
|
|||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData);
|
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData;
|
||||||
if (!DrvInfoDetailData)
|
if (AdapterGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS)
|
||||||
continue;
|
continue;
|
||||||
if (!_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID))
|
if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData))
|
||||||
{
|
{
|
||||||
PathStripPathW(DrvInfoDetailData->InfFileName);
|
HeapFree(Heap, 0, DrvInfoDetailData);
|
||||||
LOG(WINTUN_LOG_INFO, L"Removing existing driver");
|
continue;
|
||||||
if (!SetupUninstallOEMInfW(DrvInfoDetailData->InfFileName, SUOI_FORCEDELETE, NULL))
|
}
|
||||||
{
|
PathStripPathW(DrvInfoDetailData->InfFileName);
|
||||||
LOG_LAST_ERROR(L"Unable to remove existing driver");
|
LOG(WINTUN_LOG_INFO, L"Removing existing driver");
|
||||||
Result = Result != ERROR_SUCCESS ? Result : GetLastError();
|
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);
|
HeapFree(Heap, 0, DrvInfoDetailData);
|
||||||
}
|
}
|
||||||
@ -597,189 +481,6 @@ cleanupDeviceInfoSet:
|
|||||||
return Result;
|
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 (GetLastError() == ERROR_NO_MORE_ITEMS)
|
|
||||||
break;
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
Result = Result != ERROR_SUCCESS ? Result : GetLastError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs or updates Wintun driver.
|
* Installs or updates Wintun driver.
|
||||||
*
|
*
|
||||||
@ -794,7 +495,7 @@ WINTUN_STATUS DriverInstallOrUpdate(VOID)
|
|||||||
SP_DEVINFO_DATA_LIST *ExistingAdapters = NULL;
|
SP_DEVINFO_DATA_LIST *ExistingAdapters = NULL;
|
||||||
if (IsDriverLoaded())
|
if (IsDriverLoaded())
|
||||||
{
|
{
|
||||||
DisableWintunAdapters(DevInfo, &ExistingAdapters);
|
AdapterDisableAllOurs(DevInfo, &ExistingAdapters);
|
||||||
LOG(WINTUN_LOG_INFO, L"Waiting for driver to unload from kernel");
|
LOG(WINTUN_LOG_INFO, L"Waiting for driver to unload from kernel");
|
||||||
if (!EnsureDriverUnloaded())
|
if (!EnsureDriverUnloaded())
|
||||||
LOG(WINTUN_LOG_WARN, L"Unable to unload driver, which means a reboot will likely be required");
|
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:;
|
cleanupAdapters:;
|
||||||
if (ExistingAdapters)
|
if (ExistingAdapters)
|
||||||
{
|
{
|
||||||
EnableWintunAdapters(DevInfo, ExistingAdapters);
|
AdapterEnableAll(DevInfo, ExistingAdapters);
|
||||||
while (ExistingAdapters)
|
while (ExistingAdapters)
|
||||||
{
|
{
|
||||||
SP_DEVINFO_DATA_LIST *Next = ExistingAdapters->Next;
|
SP_DEVINFO_DATA_LIST *Next = ExistingAdapters->Next;
|
||||||
@ -834,10 +535,7 @@ cleanupAdapters:;
|
|||||||
*/
|
*/
|
||||||
WINTUN_STATUS DriverUninstall(VOID)
|
WINTUN_STATUS DriverUninstall(VOID)
|
||||||
{
|
{
|
||||||
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
AdapterDeleteAllOurs();
|
||||||
if (DevInfo == INVALID_HANDLE_VALUE)
|
|
||||||
return LOG_LAST_ERROR(L"Failed to get present class devices");
|
|
||||||
RemoveWintunAdapters(DevInfo);
|
|
||||||
DWORD Result = RemoveDriver();
|
DWORD Result = RemoveDriver();
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
LOG_ERROR(L"Failed to uninstall driver", Result);
|
LOG_ERROR(L"Failed to uninstall driver", Result);
|
||||||
|
12
api/driver.h
12
api/driver.h
@ -7,20 +7,14 @@
|
|||||||
|
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <SetupAPI.h>
|
|
||||||
|
|
||||||
#define WINTUN_HWID L"Wintun"
|
#define WINTUN_HWID L"Wintun"
|
||||||
|
|
||||||
_Return_type_success_(return != NULL) SP_DRVINFO_DETAIL_DATA_W *DriverGetDrvInfoDetail(
|
BOOL
|
||||||
_In_ HDEVINFO DevInfo,
|
DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids);
|
||||||
_In_opt_ SP_DEVINFO_DATA *DevInfoData,
|
|
||||||
_In_ SP_DRVINFO_DATA_W *DrvInfoData);
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData);
|
DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData);
|
||||||
|
|
||||||
_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE
|
|
||||||
DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId);
|
|
||||||
|
|
||||||
#if defined(HAVE_EV) || defined(HAVE_WHQL)
|
#if defined(HAVE_EV) || defined(HAVE_WHQL)
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ cleanupLeaveCriticalSection:
|
|||||||
|
|
||||||
_Check_return_
|
_Check_return_
|
||||||
HANDLE
|
HANDLE
|
||||||
TakeNameMutex(_In_z_ const WCHAR *Pool)
|
NamespaceTakeMutex(_In_z_ const WCHAR *Pool)
|
||||||
{
|
{
|
||||||
HANDLE Mutex = NULL;
|
HANDLE Mutex = NULL;
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ cleanupSha256:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ReleaseNameMutex(_In_ HANDLE Mutex)
|
NamespaceReleaseMutex(_In_ HANDLE Mutex)
|
||||||
{
|
{
|
||||||
ReleaseMutex(Mutex);
|
ReleaseMutex(Mutex);
|
||||||
CloseHandle(Mutex);
|
CloseHandle(Mutex);
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
|
|
||||||
_Check_return_
|
_Check_return_
|
||||||
HANDLE
|
HANDLE
|
||||||
TakeNameMutex(_In_z_ const WCHAR *Pool);
|
NamespaceTakeMutex(_In_z_ const WCHAR *Pool);
|
||||||
|
|
||||||
void
|
void
|
||||||
ReleaseNameMutex(_In_ HANDLE Mutex);
|
NamespaceReleaseMutex(_In_ HANDLE Mutex);
|
||||||
|
|
||||||
void
|
void
|
||||||
NamespaceInit();
|
NamespaceInit();
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "adapter.h"
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "devmgmt.h"
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "namespace.h"
|
#include "namespace.h"
|
||||||
|
@ -49,7 +49,7 @@ OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGL
|
|||||||
TimeLeft = 0;
|
TimeLeft = 0;
|
||||||
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
LOG(WINTUN_LOG_ERR, "Timeout waiting");
|
LOG(WINTUN_LOG_ERR, L"Timeout waiting");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD
|
|||||||
TimeLeft = 0;
|
TimeLeft = 0;
|
||||||
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
LOG(WINTUN_LOG_ERR, "Timeout waiting");
|
LOG(WINTUN_LOG_ERR, L"Timeout waiting");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -427,7 +427,7 @@ RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD T
|
|||||||
TimeLeft = 0;
|
TimeLeft = 0;
|
||||||
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
LOG(WINTUN_LOG_ERR, "Timeout waiting");
|
LOG(WINTUN_LOG_ERR, L"Timeout waiting");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ ResourceCopyToFile(
|
|||||||
DWORD SizeResource;
|
DWORD SizeResource;
|
||||||
DWORD Result = ResourceGetAddress(ResourceName, &LockedResource, &SizeResource);
|
DWORD Result = ResourceGetAddress(ResourceName, &LockedResource, &SizeResource);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
return LOG_ERROR("Failed to locate resource", Result);
|
return LOG_ERROR(L"Failed to locate resource", Result);
|
||||||
HANDLE DestinationHandle = CreateFileW(
|
HANDLE DestinationHandle = CreateFileW(
|
||||||
DestinationPath,
|
DestinationPath,
|
||||||
GENERIC_WRITE,
|
GENERIC_WRITE,
|
||||||
|
Loading…
Reference in New Issue
Block a user