api: simplify driver removal

When we install the Wintun driver to the store, we get exact oem<nn>.inf
filename of the driver in the store we just installed. Since the
installation should be only temporarily, we should uninstall only the
driver we installed.

This also eliminates the need for iterating driver store speeding up
things.

The code we removed was inherited from the installer.dll, where it made
perfect sense to remove all installed Wintun drivers in the update
process.

Suggested-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2020-10-30 09:53:09 +01:00
parent eeb42a5f12
commit abf6962144
7 changed files with 31 additions and 123 deletions

View File

@ -123,6 +123,15 @@ GetDeviceRegistryMultiString(
} }
} }
static BOOL
IsOurHardwareID(_In_z_ const WCHAR *Hwids)
{
for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
if (!_wcsicmp(Hwids, WINTUN_HWID))
return TRUE;
return FALSE;
}
static WINTUN_STATUS static WINTUN_STATUS
IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOOL *IsOurs) IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOOL *IsOurs)
{ {
@ -130,7 +139,7 @@ IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOO
DWORD Result = GetDeviceRegistryMultiString(DevInfo, DevInfoData, SPDRP_HARDWAREID, &Hwids); DWORD Result = GetDeviceRegistryMultiString(DevInfo, DevInfoData, SPDRP_HARDWAREID, &Hwids);
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
return LOG(WINTUN_LOG_ERR, L"Failed to query hardware ID"), Result; return LOG(WINTUN_LOG_ERR, L"Failed to query hardware ID"), Result;
*IsOurs = DriverIsOurHardwareID(Hwids); *IsOurs = IsOurHardwareID(Hwids);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -869,6 +878,15 @@ cleanupQueriedStore:
return Result; return Result;
} }
static BOOL
IsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData)
{
return DrvInfoDetailData->CompatIDsOffset > 1 && !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID) ||
DrvInfoDetailData->CompatIDsLength &&
IsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset);
}
static BOOL static BOOL
IsNewer(_In_ const SP_DRVINFO_DATA_W *DrvInfoData, _In_ const FILETIME *DriverDate, _In_ DWORDLONG DriverVersion) IsNewer(_In_ const SP_DRVINFO_DATA_W *DrvInfoData, _In_ const FILETIME *DriverDate, _In_ DWORDLONG DriverVersion)
{ {
@ -1038,7 +1056,7 @@ CreateAdapter(
LOG(WINTUN_LOG_WARN, L"Failed getting driver info detail"); LOG(WINTUN_LOG_WARN, L"Failed getting driver info detail");
continue; continue;
} }
if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData)) if (!IsOurDrvInfoDetail(DrvInfoDetailData))
{ {
HeapFree(ModuleHeap, 0, DrvInfoDetailData); HeapFree(ModuleHeap, 0, DrvInfoDetailData);
continue; continue;
@ -1581,14 +1599,22 @@ WintunCreateAdapter(
} }
LOG(WINTUN_LOG_INFO, L"Installing driver"); LOG(WINTUN_LOG_INFO, L"Installing driver");
if (!SetupCopyOEMInfW(InfPath, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL)) WCHAR InfStorePath[MAX_PATH];
WCHAR *InfStoreFilename;
if (!SetupCopyOEMInfW(InfPath, NULL, SPOST_PATH, 0, InfStorePath, _countof(InfStorePath), NULL, &InfStoreFilename))
{ {
Result = LOG_LAST_ERROR(L"Could not install driver to store"); Result = LOG_LAST_ERROR(L"Could not install driver to store");
goto cleanupDelete; goto cleanupDelete;
} }
Result = CreateAdapter(InfPath, Pool, Name, RequestedGUID, Adapter, RebootRequired); Result = CreateAdapter(InfPath, Pool, Name, RequestedGUID, Adapter, RebootRequired);
DriverRemoveAllOurs();
LOG(WINTUN_LOG_INFO, L"Removing driver");
if (!SetupUninstallOEMInfW(InfStoreFilename, SUOI_FORCEDELETE, NULL))
{
LOG_LAST_ERROR(L"Unable to remove existing driver");
Result = Result != ERROR_SUCCESS ? Result : GetLastError();
}
cleanupDelete: cleanupDelete:
DeleteFileW(CatPath); DeleteFileW(CatPath);
DeleteFileW(SysPath); DeleteFileW(SysPath);

View File

@ -9,6 +9,7 @@
#include <SetupAPI.h> #include <SetupAPI.h>
#define MAX_INSTANCE_ID MAX_PATH /* TODO: Is MAX_PATH always enough? */ #define MAX_INSTANCE_ID MAX_PATH /* TODO: Is MAX_PATH always enough? */
#define WINTUN_HWID L"Wintun"
typedef struct _SP_DEVINFO_DATA_LIST typedef struct _SP_DEVINFO_DATA_LIST
{ {

View File

@ -196,7 +196,6 @@
<ClInclude Include="api.h" /> <ClInclude Include="api.h" />
<ClInclude Include="adapter.h" /> <ClInclude Include="adapter.h" />
<ClInclude Include="atomic.h" /> <ClInclude Include="atomic.h" />
<ClInclude Include="driver.h" />
<ClInclude Include="logger.h" /> <ClInclude Include="logger.h" />
<ClInclude Include="namespace.h" /> <ClInclude Include="namespace.h" />
<ClInclude Include="nci.h" /> <ClInclude Include="nci.h" />
@ -208,7 +207,6 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="api.c" /> <ClCompile Include="api.c" />
<ClCompile Include="adapter.c" /> <ClCompile Include="adapter.c" />
<ClCompile Include="driver.c" />
<ClCompile Include="logger.c" /> <ClCompile Include="logger.c" />
<ClCompile Include="namespace.c" /> <ClCompile Include="namespace.c" />
<ClCompile Include="nci.c" /> <ClCompile Include="nci.c" />

View File

@ -46,9 +46,6 @@
<ClInclude Include="resource.h"> <ClInclude Include="resource.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="driver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="adapter.h"> <ClInclude Include="adapter.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -84,9 +81,6 @@
<ClCompile Include="resource.c"> <ClCompile Include="resource.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="driver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="adapter.c"> <ClCompile Include="adapter.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View File

@ -1,72 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
*/
#include "pch.h"
#pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */
BOOL
DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids)
{
for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
if (!_wcsicmp(Hwids, WINTUN_HWID))
return TRUE;
return FALSE;
}
BOOL
DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData)
{
return DrvInfoDetailData->CompatIDsOffset > 1 && !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID) ||
DrvInfoDetailData->CompatIDsLength &&
DriverIsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset);
}
WINTUN_STATUS
DriverRemoveAllOurs(void)
{
HDEVINFO DevInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, 0);
if (!DevInfo)
return LOG_LAST_ERROR(L"Failed to request device information");
DWORD Result = ERROR_SUCCESS;
if (!SetupDiBuildDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER))
{
Result = LOG_LAST_ERROR(L"Failed to build list of drivers");
goto cleanupDeviceInfoSet;
}
for (DWORD EnumIndex = 0;; ++EnumIndex)
{
SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(DrvInfoData) };
if (!SetupDiEnumDriverInfoW(DevInfo, NULL, SPDIT_CLASSDRIVER, EnumIndex, &DrvInfoData))
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break;
continue;
}
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData;
if (AdapterGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS)
{
LOG(WINTUN_LOG_WARN, L"Failed getting driver info detail");
continue;
}
if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData))
{
HeapFree(ModuleHeap, 0, DrvInfoDetailData);
continue;
}
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(ModuleHeap, 0, DrvInfoDetailData);
}
SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER);
cleanupDeviceInfoSet:
SetupDiDestroyDeviceInfoList(DevInfo);
return Result;
}

View File

@ -1,38 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
*/
#pragma once
#include "wintun.h"
#include <Windows.h>
#define WINTUN_HWID L"Wintun"
/**
* Tests if any of the hardware IDs match ours.
*
* @param Hwids Multi-string containing a list of hardware IDs.
*
* @return TRUE on match; FALSE otherwise.
*/
BOOL
DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids);
/**
* Tests if hardware ID or any of the compatible IDs match ours.
*
* @param DrvInfoDetailData Detailed information about a particular driver information structure.
*
* @return TRUE on match; FALSE otherwise.
*/
BOOL
DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData);
/**
* Removes all Wintun drivers from the driver store.
*
* @return ERROR_SUCCESS on success or the adapter was not found; Win32 error code otherwise.
*/
WINTUN_STATUS DriverRemoveAllOurs(void);

View File

@ -8,7 +8,6 @@
#include "adapter.h" #include "adapter.h"
#include "atomic.h" #include "atomic.h"
#include "api.h" #include "api.h"
#include "driver.h"
#include "logger.h" #include "logger.h"
#include "namespace.h" #include "namespace.h"
#include "nci.h" #include "nci.h"