diff --git a/api/adapter.c b/api/adapter.c index b9d131c..7f2824a 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -5,6 +5,8 @@ #include "pch.h" +#pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */ + #define WAIT_FOR_REGISTRY_TIMEOUT 10000 /* ms */ #define MAX_POOL_DEVICE_TYPE (MAX_POOL + 8) /* Should accommodate a pool name with " Tunnel" appended */ @@ -819,8 +821,106 @@ IsNewer(_In_ const SP_DRVINFO_DATA_W *DrvInfoData, _In_ const FILETIME *DriverDa return FALSE; } -WINTUN_STATUS WINAPI -WintunCreateAdapter( +#if defined(HAVE_EV) || defined(HAVE_WHQL) + +/* We can't use RtlGetVersion, because appcompat's aclayers.dll shims it to report Vista + * when run from legacy contexts. So, we instead use the undocumented RtlGetNtVersionNumbers. + * + * Another way would be reading from the PEB directly: + * ((DWORD *)NtCurrentTeb()->ProcessEnvironmentBlock)[sizeof(void *) == 8 ? 70 : 41] + * Or just read from KUSER_SHARED_DATA the same way on 32-bit and 64-bit: + * *(DWORD *)0x7FFE026C + */ +extern VOID NTAPI +RtlGetNtVersionNumbers(_Out_opt_ DWORD *MajorVersion, _Out_opt_ DWORD *MinorVersion, _Out_opt_ DWORD *BuildNumber); + +static BOOL +HaveWHQL() +{ +# if defined(HAVE_EV) && defined(HAVE_WHQL) + DWORD MajorVersion; + RtlGetNtVersionNumbers(&MajorVersion, NULL, NULL); + return MajorVersion >= 10; +# elif defined(HAVE_EV) + return FALSE; +# elif defined(HAVE_WHQL) + return TRUE; +# endif +} + +static WINTUN_STATUS +InstallCertificate(_In_z_ const WCHAR *SignedResource) +{ + LOG(WINTUN_LOG_INFO, L"Trusting code signing certificate"); + const VOID *LockedResource; + DWORD SizeResource; + DWORD Result = ResourceGetAddress(SignedResource, &LockedResource, &SizeResource); + if (Result != ERROR_SUCCESS) + return LOG(WINTUN_LOG_ERR, L"Failed to locate resource"), Result; + const CERT_BLOB CertBlob = { .cbData = SizeResource, .pbData = (BYTE *)LockedResource }; + HCERTSTORE QueriedStore; + if (!CryptQueryObject( + CERT_QUERY_OBJECT_BLOB, + &CertBlob, + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, + CERT_QUERY_FORMAT_FLAG_ALL, + 0, + 0, + 0, + 0, + &QueriedStore, + 0, + NULL)) + 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) + { + Result = LOG_LAST_ERROR(L"Failed to open store"); + goto cleanupQueriedStore; + } + LPSTR CodeSigningOid[] = { szOID_PKIX_KP_CODE_SIGNING }; + CERT_ENHKEY_USAGE EnhancedUsage = { .cUsageIdentifier = 1, .rgpszUsageIdentifier = CodeSigningOid }; + for (const CERT_CONTEXT *CertContext = NULL; (CertContext = CertFindCertificateInStore( + QueriedStore, + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, + CERT_FIND_ENHKEY_USAGE, + &EnhancedUsage, + CertContext)) != NULL;) + { + CERT_EXTENSION *Ext = CertFindExtension( + szOID_BASIC_CONSTRAINTS2, CertContext->pCertInfo->cExtension, CertContext->pCertInfo->rgExtension); + CERT_BASIC_CONSTRAINTS2_INFO Constraints; + DWORD Size = sizeof(Constraints); + if (Ext && + CryptDecodeObjectEx( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + szOID_BASIC_CONSTRAINTS2, + Ext->Value.pbData, + Ext->Value.cbData, + 0, + NULL, + &Constraints, + &Size) && + !Constraints.fCA) + if (!CertAddCertificateContextToStore(TrustedStore, CertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) + { + LOG_LAST_ERROR(L"Failed to add certificate to store"); + Result = Result != ERROR_SUCCESS ? Result : GetLastError(); + } + } + CertCloseStore(TrustedStore, 0); +cleanupQueriedStore: + CertCloseStore(QueriedStore, 0); + return Result; +} + +#endif + +static WINTUN_STATUS +CreateAdapter( + _In_z_count_c_(MAX_PATH) const WCHAR *InfPath, _In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name, _In_opt_ const GUID *RequestedGUID, @@ -856,7 +956,19 @@ WintunCreateAdapter( Result = LOG_LAST_ERROR(L"Creating new device information element failed"); goto cleanupDevInfo; } - SetQuietInstall(DevInfo, &DevInfoData); + SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) }; + if (!SetupDiGetDeviceInstallParamsW(DevInfo, &DevInfoData, &DevInstallParams)) + { + Result = LOG_LAST_ERROR(L"Retrieving device installation parameters failed"); + goto cleanupDevInfo; + } + DevInstallParams.Flags |= DI_QUIETINSTALL | DI_ENUMSINGLEINF; + wcscpy_s(DevInstallParams.DriverPath, _countof(DevInstallParams.DriverPath), InfPath); + if (!SetupDiSetDeviceInstallParamsW(DevInfo, &DevInfoData, &DevInstallParams)) + { + Result = LOG_LAST_ERROR(L"Setting device installation parameters failed"); + goto cleanupDevInfo; + } if (!SetupDiSetSelectedDevice(DevInfo, &DevInfoData)) { @@ -1091,6 +1203,78 @@ cleanupMutex: return Result; } +WINTUN_STATUS WINAPI +WintunCreateAdapter( + _In_z_count_c_(MAX_POOL) const WCHAR *Pool, + _In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name, + _In_opt_ const GUID *RequestedGUID, + _Out_ WINTUN_ADAPTER **Adapter, + _Inout_ BOOL *RebootRequired) +{ +#if defined(HAVE_EV) || defined(HAVE_WHQL) + WCHAR WindowsDirectory[MAX_PATH]; + if (!GetWindowsDirectoryW(WindowsDirectory, _countof(WindowsDirectory))) + return LOG_LAST_ERROR(L"Failed to get Windows folder"); + WCHAR WindowsTempDirectory[MAX_PATH]; + if (!PathCombineW(WindowsTempDirectory, WindowsDirectory, L"Temp")) + return ERROR_BUFFER_OVERFLOW; + UCHAR RandomBytes[32] = { 0 }; +# pragma warning(suppress : 6387) + if (!RtlGenRandom(RandomBytes, sizeof(RandomBytes))) + return LOG_LAST_ERROR(L"Failed to generate random"); + WCHAR RandomSubDirectory[sizeof(RandomBytes) * 2 + 1]; + for (int i = 0; i < sizeof(RandomBytes); ++i) + swprintf_s(&RandomSubDirectory[i * 2], 3, L"%02x", RandomBytes[i]); + WCHAR RandomTempSubDirectory[MAX_PATH]; + if (!PathCombineW(RandomTempSubDirectory, WindowsTempDirectory, RandomSubDirectory)) + return ERROR_BUFFER_OVERFLOW; + if (!CreateDirectoryW(RandomTempSubDirectory, SecurityAttributes)) + return LOG_LAST_ERROR(L"Failed to create temporary folder"); + + DWORD Result = ERROR_SUCCESS; + WCHAR CatPath[MAX_PATH] = { 0 }; + WCHAR SysPath[MAX_PATH] = { 0 }; + WCHAR InfPath[MAX_PATH] = { 0 }; + if (!PathCombineW(CatPath, RandomTempSubDirectory, L"wintun.cat") || + !PathCombineW(SysPath, RandomTempSubDirectory, L"wintun.sys") || + !PathCombineW(InfPath, RandomTempSubDirectory, L"wintun.inf")) + { + Result = ERROR_BUFFER_OVERFLOW; + goto cleanupDirectory; + } + + BOOL UseWHQL = HaveWHQL(); + if (!UseWHQL && (Result = InstallCertificate(L"wintun.sys")) != ERROR_SUCCESS) + LOG(WINTUN_LOG_WARN, L"Unable to install code signing certificate"); + + LOG(WINTUN_LOG_INFO, L"Copying resources to temporary path"); + if ((Result = ResourceCopyToFile(CatPath, UseWHQL ? L"wintun-whql.cat" : L"wintun.cat")) != ERROR_SUCCESS || + (Result = ResourceCopyToFile(SysPath, UseWHQL ? L"wintun-whql.sys" : L"wintun.sys")) != ERROR_SUCCESS || + (Result = ResourceCopyToFile(InfPath, UseWHQL ? L"wintun-whql.inf" : L"wintun.inf")) != ERROR_SUCCESS) + { + LOG(WINTUN_LOG_ERR, L"Failed to copy resources"); + goto cleanupDelete; + } + + LOG(WINTUN_LOG_INFO, L"Installing driver"); + if (!SetupCopyOEMInfW(InfPath, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL)) + { + Result = LOG_LAST_ERROR(L"Could not install driver to store"); + goto cleanupDelete; + } + + Result = CreateAdapter(InfPath, Pool, Name, RequestedGUID, Adapter, RebootRequired); + DriverRemoveAllOurs(); +cleanupDelete: + DeleteFileW(CatPath); + DeleteFileW(SysPath); + DeleteFileW(InfPath); +cleanupDirectory: + RemoveDirectoryW(RandomTempSubDirectory); + return Result; +#endif +} + WINTUN_STATUS WINAPI WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequired) { diff --git a/api/driver.c b/api/driver.c index fffd445..f57c36b 100644 --- a/api/driver.c +++ b/api/driver.c @@ -26,330 +26,7 @@ DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData) #if defined(HAVE_EV) || defined(HAVE_WHQL) -/* We can't use RtlGetVersion, because appcompat's aclayers.dll shims it to report Vista - * when run from legacy contexts. So, we instead use the undocumented RtlGetNtVersionNumbers. - * - * Another way would be reading from the PEB directly: - * ((DWORD *)NtCurrentTeb()->ProcessEnvironmentBlock)[sizeof(void *) == 8 ? 70 : 41] - * Or just read from KUSER_SHARED_DATA the same way on 32-bit and 64-bit: - * *(DWORD *)0x7FFE026C - */ -extern VOID NTAPI -RtlGetNtVersionNumbers(_Out_opt_ DWORD *MajorVersion, _Out_opt_ DWORD *MinorVersion, _Out_opt_ DWORD *BuildNumber); - -static BOOL -HaveWHQL() -{ -# if defined(HAVE_EV) && defined(HAVE_WHQL) - DWORD MajorVersion; - RtlGetNtVersionNumbers(&MajorVersion, NULL, NULL); - return MajorVersion >= 10; -# elif defined(HAVE_EV) - return FALSE; -# elif defined(HAVE_WHQL) - return TRUE; -# endif -} - -static const CHAR * -SkipWSpace(_In_ const CHAR *Beg, _In_ const CHAR *End) -{ - for (; Beg < End && iswspace(*Beg); ++Beg) - ; - return Beg; -} - -static const CHAR * -SkipNonLF(_In_ const CHAR *Beg, _In_ const CHAR *End) -{ - for (; Beg < End && *Beg != '\n'; ++Beg) - ; - return Beg; -} - -WINTUN_STATUS -DriverGetVersion(_Out_ FILETIME *DriverDate, _Out_ DWORDLONG *DriverVersion) -{ - const VOID *LockedResource; - DWORD SizeResource; - DWORD Result = ResourceGetAddress(HaveWHQL() ? L"wintun-whql.inf" : L"wintun.inf", &LockedResource, &SizeResource); - if (Result != ERROR_SUCCESS) - return LOG(WINTUN_LOG_ERR, L"Failed to locate resource"), Result; - enum - { - SectNone, - SectUnknown, - SectVersion - } Section = SectNone; - for (const CHAR *Inf = (const CHAR *)LockedResource, *InfEnd = Inf + SizeResource; Inf < InfEnd; ++Inf) - { - if (*Inf == ';') - { - Inf = SkipNonLF(Inf + 1, InfEnd); - continue; - } - Inf = SkipWSpace(Inf, InfEnd); - if (*Inf == '[') - { - Section = Inf + 9 <= InfEnd && !_strnicmp(Inf, "[Version]", 9) ? SectVersion : SectUnknown; - } - else if (Section == SectVersion) - { - if (Inf + 9 <= InfEnd && !_strnicmp(Inf, "DriverVer", 9)) - { - Inf = SkipWSpace(Inf + 9, InfEnd); - if (Inf < InfEnd && *Inf == '=') - { - Inf = SkipWSpace(Inf + 1, InfEnd); - /* Duplicate buffer, as RT_RCDATA resource is not guaranteed to be zero-terminated. */ - CHAR buf[0x100]; - size_t n = InfEnd - Inf; - if (n >= _countof(buf)) - n = _countof(buf) - 1; - strncpy_s(buf, _countof(buf), Inf, n); - buf[n] = 0; - const CHAR *p = buf; - CHAR *p_next; - unsigned long date[3] = { 0, 0, 0 }; - for (size_t i = 0;; ++i, ++p) - { - date[i] = strtoul(p, &p_next, 10); - p = p_next; - if (i >= _countof(date) - 1) - break; - if (*p != '/' && *p != '-') - { - LOG(WINTUN_LOG_ERR, L"Unexpected date delimiter"); - return ERROR_INVALID_DATA; - } - } - if (date[0] < 1 || date[0] > 12 || date[1] < 1 || date[1] > 31 || date[2] < 1601 || date[2] > 30827) - { - LOG(WINTUN_LOG_ERR, L"Invalid date"); - return ERROR_INVALID_DATA; - } - const SYSTEMTIME st = { .wYear = (WORD)date[2], .wMonth = (WORD)date[0], .wDay = (WORD)date[1] }; - SystemTimeToFileTime(&st, DriverDate); - p = SkipWSpace(p, buf + n); - ULONGLONG version[4] = { 0, 0, 0, 0 }; - if (*p == ',') - { - p = SkipWSpace(p + 1, buf + n); - for (size_t i = 0;; ++i, ++p) - { - version[i] = strtoul(p, &p_next, 10); - if (version[i] > 0xffff) - { - LOG(WINTUN_LOG_ERR, L"Version field may not exceed 65535"); - return ERROR_INVALID_DATA; - } - p = p_next; - if (i >= _countof(version) - 1 || !*p || *p == ';' || iswspace(*p)) - break; - if (*p != '.') - { - LOG(WINTUN_LOG_ERR, L"Unexpected version delimiter"); - return ERROR_INVALID_DATA; - } - } - } - *DriverVersion = (version[0] << 48) | (version[1] << 32) | (version[2] << 16) | version[3]; - return ERROR_SUCCESS; - } - } - } - Inf = SkipNonLF(Inf, InfEnd); - } - LOG(WINTUN_LOG_ERR, L"DriverVer not found in INF resource"); - return ERROR_FILE_NOT_FOUND; -} - -/* This function does not log any errors, not to flood the log when called from the EnsureDriverUnloaded() loop. */ -static BOOL IsDriverLoaded(VOID) -{ - VOID *StackBuffer[0x80]; - VOID **Drivers = StackBuffer; - DWORD Size = 0; - if (!EnumDeviceDrivers(Drivers, sizeof(StackBuffer), &Size)) - return FALSE; - if (Size > sizeof(StackBuffer)) - { - HANDLE Heap = GetProcessHeap(); - Drivers = HeapAlloc(Heap, 0, Size); - if (!Drivers) - { - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; - } - if (!EnumDeviceDrivers(Drivers, Size, &Size)) - { - DWORD Result = GetLastError(); - HeapFree(Heap, 0, Drivers); - SetLastError(Result); - return FALSE; - } - } - BOOL Found = FALSE; - for (DWORD i = Size / sizeof(Drivers[0]); i-- > 0;) - { - WCHAR MaybeWintun[11]; - if (GetDeviceDriverBaseNameW(Drivers[i], MaybeWintun, _countof(MaybeWintun)) == 10 && - !_wcsicmp(MaybeWintun, L"wintun.sys")) - { - Found = TRUE; - break; - } - } - if (Drivers != StackBuffer) - HeapFree(GetProcessHeap(), 0, Drivers); - SetLastError(ERROR_SUCCESS); - return Found; -} - -static BOOL EnsureDriverUnloaded(VOID) -{ - BOOL Loaded; - for (int i = 0; (Loaded = IsDriverLoaded()) != 0 && i < 300; ++i) - Sleep(50); - return !Loaded; -} - -static WINTUN_STATUS -InstallCertificate(_In_z_ const WCHAR *SignedResource) -{ - LOG(WINTUN_LOG_INFO, L"Trusting code signing certificate"); - const VOID *LockedResource; - DWORD SizeResource; - DWORD Result = ResourceGetAddress(SignedResource, &LockedResource, &SizeResource); - if (Result != ERROR_SUCCESS) - return LOG(WINTUN_LOG_ERR, L"Failed to locate resource"), Result; - const CERT_BLOB CertBlob = { .cbData = SizeResource, .pbData = (BYTE *)LockedResource }; - HCERTSTORE QueriedStore; - if (!CryptQueryObject( - CERT_QUERY_OBJECT_BLOB, - &CertBlob, - CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, - CERT_QUERY_FORMAT_FLAG_ALL, - 0, - 0, - 0, - 0, - &QueriedStore, - 0, - NULL)) - 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) - { - Result = LOG_LAST_ERROR(L"Failed to open store"); - goto cleanupQueriedStore; - } - LPSTR CodeSigningOid[] = { szOID_PKIX_KP_CODE_SIGNING }; - CERT_ENHKEY_USAGE EnhancedUsage = { .cUsageIdentifier = 1, .rgpszUsageIdentifier = CodeSigningOid }; - for (const CERT_CONTEXT *CertContext = NULL; (CertContext = CertFindCertificateInStore( - QueriedStore, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, - CERT_FIND_ENHKEY_USAGE, - &EnhancedUsage, - CertContext)) != NULL;) - { - CERT_EXTENSION *Ext = CertFindExtension( - szOID_BASIC_CONSTRAINTS2, CertContext->pCertInfo->cExtension, CertContext->pCertInfo->rgExtension); - CERT_BASIC_CONSTRAINTS2_INFO Constraints; - DWORD Size = sizeof(Constraints); - if (Ext && - CryptDecodeObjectEx( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - szOID_BASIC_CONSTRAINTS2, - Ext->Value.pbData, - Ext->Value.cbData, - 0, - NULL, - &Constraints, - &Size) && - !Constraints.fCA) - if (!CertAddCertificateContextToStore(TrustedStore, CertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) - { - LOG_LAST_ERROR(L"Failed to add certificate to store"); - Result = Result != ERROR_SUCCESS ? Result : GetLastError(); - } - } - CertCloseStore(TrustedStore, 0); -cleanupQueriedStore: - CertCloseStore(QueriedStore, 0); - return Result; -} - -static WINTUN_STATUS -InstallDriver(_In_ BOOL UpdateExisting) -{ - WCHAR WindowsDirectory[MAX_PATH]; - if (!GetWindowsDirectoryW(WindowsDirectory, _countof(WindowsDirectory))) - return LOG_LAST_ERROR(L"Failed to get Windows folder"); - WCHAR WindowsTempDirectory[MAX_PATH]; - if (!PathCombineW(WindowsTempDirectory, WindowsDirectory, L"Temp")) - return ERROR_BUFFER_OVERFLOW; - UCHAR RandomBytes[32] = { 0 }; -# pragma warning(suppress : 6387) - if (!RtlGenRandom(RandomBytes, sizeof(RandomBytes))) - return LOG_LAST_ERROR(L"Failed to generate random"); - WCHAR RandomSubDirectory[sizeof(RandomBytes) * 2 + 1]; - for (int i = 0; i < sizeof(RandomBytes); ++i) - swprintf_s(&RandomSubDirectory[i * 2], 3, L"%02x", RandomBytes[i]); - WCHAR RandomTempSubDirectory[MAX_PATH]; - if (!PathCombineW(RandomTempSubDirectory, WindowsTempDirectory, RandomSubDirectory)) - return ERROR_BUFFER_OVERFLOW; - if (!CreateDirectoryW(RandomTempSubDirectory, SecurityAttributes)) - return LOG_LAST_ERROR(L"Failed to create temporary folder"); - - DWORD Result = ERROR_SUCCESS; - WCHAR CatPath[MAX_PATH] = { 0 }; - WCHAR SysPath[MAX_PATH] = { 0 }; - WCHAR InfPath[MAX_PATH] = { 0 }; - if (!PathCombineW(CatPath, RandomTempSubDirectory, L"wintun.cat") || - !PathCombineW(SysPath, RandomTempSubDirectory, L"wintun.sys") || - !PathCombineW(InfPath, RandomTempSubDirectory, L"wintun.inf")) - { - Result = ERROR_BUFFER_OVERFLOW; - goto cleanupDirectory; - } - - BOOL UseWHQL = HaveWHQL(); - if (!UseWHQL && (Result = InstallCertificate(L"wintun.sys")) != ERROR_SUCCESS) - LOG(WINTUN_LOG_WARN, L"Unable to install code signing certificate"); - - LOG(WINTUN_LOG_INFO, L"Copying resources to temporary path"); - if ((Result = ResourceCopyToFile(CatPath, UseWHQL ? L"wintun-whql.cat" : L"wintun.cat")) != ERROR_SUCCESS || - (Result = ResourceCopyToFile(SysPath, UseWHQL ? L"wintun-whql.sys" : L"wintun.sys")) != ERROR_SUCCESS || - (Result = ResourceCopyToFile(InfPath, UseWHQL ? L"wintun-whql.inf" : L"wintun.inf")) != ERROR_SUCCESS) - { - LOG(WINTUN_LOG_ERR, L"Failed to copy resources"); - goto cleanupDelete; - } - - LOG(WINTUN_LOG_INFO, L"Installing driver"); - if (!SetupCopyOEMInfW(InfPath, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL)) - Result = LOG_LAST_ERROR(L"Could not install driver to store"); - BOOL RebootRequired = FALSE; - if (UpdateExisting && - !UpdateDriverForPlugAndPlayDevicesW( - NULL, WINTUN_HWID, InfPath, INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, &RebootRequired)) - LOG_LAST_ERROR(L"Could not update existing adapters"); - if (RebootRequired) - LOG(WINTUN_LOG_WARN, L"A reboot might be required, which really should not be the case"); - -cleanupDelete: - DeleteFileW(CatPath); - DeleteFileW(SysPath); - DeleteFileW(InfPath); -cleanupDirectory: - RemoveDirectoryW(RandomTempSubDirectory); - return Result; -} - -static WINTUN_STATUS RemoveDriver(VOID) +WINTUN_STATUS DriverRemoveAllOurs(VOID) { HDEVINFO DevInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, 0); if (!DevInfo) @@ -396,57 +73,4 @@ cleanupDeviceInfoSet: return Result; } -WINTUN_STATUS DriverInstallOrUpdate(VOID) -{ - HANDLE Heap = GetProcessHeap(); - 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_DEVINFO_DATA_LIST *ExistingAdapters = NULL; - if (IsDriverLoaded()) - { - 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"); - } - DWORD Result = ERROR_SUCCESS; - if ((Result = RemoveDriver()) != ERROR_SUCCESS) - { - LOG(WINTUN_LOG_ERR, L"Failed to uninstall old drivers"); - goto cleanupAdapters; - } - if ((Result = InstallDriver(!!ExistingAdapters)) != ERROR_SUCCESS) - { - LOG(WINTUN_LOG_ERR, L"Failed to install driver"); - goto cleanupAdapters; - } - LOG(WINTUN_LOG_INFO, L"Installation successful"); - -cleanupAdapters:; - if (ExistingAdapters) - { - AdapterEnableAll(DevInfo, ExistingAdapters); - while (ExistingAdapters) - { - SP_DEVINFO_DATA_LIST *Next = ExistingAdapters->Next; - HeapFree(Heap, 0, ExistingAdapters); - ExistingAdapters = Next; - } - } - SetupDiDestroyDeviceInfoList(DevInfo); - return Result; -} - -WINTUN_STATUS DriverUninstall(VOID) -{ - AdapterDeleteAllOurs(); - DWORD Result = RemoveDriver(); - if (Result == ERROR_SUCCESS) - LOG(WINTUN_LOG_INFO, L"Uninstallation successful"); - else - LOG(WINTUN_LOG_ERR, L"Failed to uninstall driver"); - return Result; -} - #endif diff --git a/api/driver.h b/api/driver.h index 967d862..686b3d4 100644 --- a/api/driver.h +++ b/api/driver.h @@ -30,32 +30,9 @@ DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids); BOOL DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData); -#if defined(HAVE_EV) || defined(HAVE_WHQL) - /** - * Queries the version of the driver this wintun.dll is packing. + * Removes all Wintun drivers from the driver store. * - * DriverDate Pointer to a variable to receive the driver date. - * - * DriverVersion Pointer to a variable to receive the driver version. - * - * @return ERROR_SUCCESS on success; Win32 error code otherwise. + * @return ERROR_SUCCESS on success or the adapter was not found; Win32 error code otherwise. */ -WINTUN_STATUS -DriverGetVersion(_Out_ FILETIME *DriverDate, _Out_ DWORDLONG *DriverVersion); - -/** - * Installs or updates Wintun driver. - * - * @return ERROR_SUCCESS on success; Win32 error code otherwise. - */ -WINTUN_STATUS DriverInstallOrUpdate(VOID); - -/** - * Uninstalls Wintun driver. - * - * @return ERROR_SUCCESS on success; Win32 error code otherwise. - */ -WINTUN_STATUS DriverUninstall(VOID); - -#endif +WINTUN_STATUS DriverRemoveAllOurs(VOID);