api: retry on ERROR_TRANSACTION_NOT_ACTIVE when disabling dead GW detect

There seems to be a race in the TCP/IP adapter registry key. Sometimes,
the adapter TCP/IP key is created, but setting the value
EnableDeadGWDetect fails with ERROR_TRANSACTION_NOT_ACTIVE.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2020-11-17 15:30:00 +01:00
parent c18dd0a216
commit f7c2ea4ded

View File

@ -1497,14 +1497,15 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter(
}
Free(DummyStr);
HKEY TcpipInterfaceRegKey;
WCHAR TcpipInterfaceRegPath[MAX_REG_PATH];
if (!GetTcpipInterfaceRegPath(Adapter, TcpipInterfaceRegPath))
{
LastError = LOG(WINTUN_LOG_ERR, L"Failed to determine interface-specific TCP/IP network registry key path");
goto cleanupTcpipAdapterRegKey;
}
TcpipInterfaceRegKey = RegistryOpenKeyWait(
for (int Tries = 0; Tries < 300; ++Tries)
{
HKEY TcpipInterfaceRegKey = RegistryOpenKeyWait(
HKEY_LOCAL_MACHINE, TcpipInterfaceRegPath, KEY_QUERY_VALUE | KEY_SET_VALUE, WAIT_FOR_REGISTRY_TIMEOUT);
if (!TcpipInterfaceRegKey)
{
@ -1514,17 +1515,27 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter(
static const DWORD EnableDeadGWDetect = 0;
LastError = RegSetKeyValueW(
TcpipInterfaceRegKey, NULL, L"EnableDeadGWDetect", REG_DWORD, &EnableDeadGWDetect, sizeof(EnableDeadGWDetect));
if (LastError != ERROR_SUCCESS)
TcpipInterfaceRegKey,
NULL,
L"EnableDeadGWDetect",
REG_DWORD,
&EnableDeadGWDetect,
sizeof(EnableDeadGWDetect));
RegCloseKey(TcpipInterfaceRegKey);
if (LastError == ERROR_SUCCESS)
break;
if (LastError != ERROR_TRANSACTION_NOT_ACTIVE || Tries == 299)
{
LOG_ERROR(L"Failed to set EnableDeadGWDetect", LastError);
goto cleanupTcpipInterfaceRegKey;
goto cleanupTcpipAdapterRegKey;
}
Sleep(10);
}
if (!WintunSetAdapterName(Adapter, Name))
{
LastError = LOG(WINTUN_LOG_ERR, L"Failed to set adapter name");
goto cleanupTcpipInterfaceRegKey;
goto cleanupTcpipAdapterRegKey;
}
DEVPROPTYPE PropertyType;
@ -1547,7 +1558,7 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter(
if (ProblemStatus != STATUS_PNP_DEVICE_CONFIGURATION_PENDING || Tries == 999)
{
LOG_ERROR(L"Failed to setup adapter", LastError);
goto cleanupTcpipInterfaceRegKey;
goto cleanupTcpipAdapterRegKey;
}
Sleep(10);
}
@ -1556,8 +1567,6 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter(
}
LastError = ERROR_SUCCESS;
cleanupTcpipInterfaceRegKey:
RegCloseKey(TcpipInterfaceRegKey);
cleanupTcpipAdapterRegKey:
RegCloseKey(TcpipAdapterRegKey);
cleanupAdapter: