aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-10-07 06:28:28 +0000
committerJason A. Donenfeld <Jason@zx2c4.com>2021-10-11 16:12:09 +0000
commitf779da4e8865526ae70214ae2b3e34f752ad6003 (patch)
tree6bbf9048f5636abdcafbf390ee377f0607183ca6
parentapi: adapter: cleanup ROOT\NET enumerated devices on DLL load (diff)
downloadwireguard-nt-f779da4e8865526ae70214ae2b3e34f752ad6003.tar.xz
wireguard-nt-f779da4e8865526ae70214ae2b3e34f752ad6003.zip
api: adapter: replace INF Include/Needs hack with stub device
Apparently breaking the guarantee of "Universal INF"s receives the big tsk tsk, so this commit is yet another way to set SuggestedInstanceId. We create an SwDevice, with DEVPKEY_Device_ClassGuid set to GUID_DEVCLASS_NET and an empty HWID, and then create the software regkey and add the keys we need. We then destroy the SwDevice, and recreate a new one with the same instance ID, this time with the proper parameters. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--api/adapter.c171
-rw-r--r--driver/wireguard.inf2
2 files changed, 81 insertions, 92 deletions
diff --git a/api/adapter.c b/api/adapter.c
index 4d4f3c6..14a4435 100644
--- a/api/adapter.c
+++ b/api/adapter.c
@@ -537,15 +537,6 @@ WireGuardCreateAdapter(LPCWSTR Name, LPCWSTR TunnelType, const GUID *RequestedGU
goto cleanup;
}
- WCHAR InstanceIdInf[MAX_PATH];
- if (!GetWindowsDirectoryW(InstanceIdInf, _countof(InstanceIdInf)) ||
- !PathAppend(InstanceIdInf, L"INF\\wireguard-instanceid.inf"))
- {
- LastError = LOG_ERROR(ERROR_BUFFER_OVERFLOW, L"Failed to construct INF path");
- goto cleanupDeviceInstallationMutex;
- }
- DeleteFileW(InstanceIdInf);
-
HDEVINFO DevInfoExistingAdapters;
SP_DEVINFO_DATA_LIST *ExistingAdapters;
if (!DriverInstall(&DevInfoExistingAdapters, &ExistingAdapters))
@@ -560,66 +551,6 @@ WireGuardCreateAdapter(LPCWSTR Name, LPCWSTR TunnelType, const GUID *RequestedGU
if (!Adapter)
goto cleanupDriverInstall;
- if (RequestedGUID)
- {
- HANDLE InstanceIdFile = CreateFileW(
- InstanceIdInf,
- GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (InstanceIdFile == INVALID_HANDLE_VALUE)
- {
- LastError = LOG_LAST_ERROR(L"Failed to open %s for writing", InstanceIdInf);
- goto cleanupDriverInstall;
- }
- static const WCHAR InfTemplate[] =
- L"[Version]\r\n"
- L"Signature = \"$Windows NT$\"\r\n"
- L"[WireGuard.NetSetup]\r\n"
- L"AddReg = WireGuard.SuggestedInstanceId\r\n"
- L"[WireGuard.SuggestedInstanceId]\r\n"
- L"HKR,,SuggestedInstanceId,1,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X\r\n";
- WCHAR InfContents[_countof(InfTemplate)];
- BYTE *P = (BYTE *)RequestedGUID;
- _snwprintf_s(
- InfContents,
- _countof(InfContents),
- _TRUNCATE,
- InfTemplate,
- P[0],
- P[1],
- P[2],
- P[3],
- P[4],
- P[5],
- P[6],
- P[7],
- P[8],
- P[9],
- P[10],
- P[11],
- P[12],
- P[13],
- P[14],
- P[15]);
- DWORD BytesWritten;
- if (!WriteFile(
- InstanceIdFile,
- InfContents,
- (DWORD)(wcslen(InfContents) * sizeof(InfContents[0])),
- &BytesWritten,
- NULL))
- {
- LastError = LOG_LAST_ERROR(L"Failed to write bytes to %s", InstanceIdInf);
- CloseHandle(InstanceIdFile);
- goto cleanupInstanceIdFile;
- }
- CloseHandle(InstanceIdFile);
- }
-
WCHAR TunnelTypeName[MAX_ADAPTER_NAME + 8];
if (_snwprintf_s(TunnelTypeName, _countof(TunnelTypeName), _TRUNCATE, L"%s Tunnel", TunnelType) == -1)
{
@@ -649,11 +580,89 @@ WireGuardCreateAdapter(LPCWSTR Name, LPCWSTR TunnelType, const GUID *RequestedGU
LastError = LOG_ERROR(HRet, L"Failed to convert GUID");
goto cleanupAdapter;
}
+ SW_DEVICE_CREATE_CTX CreateContext = { .DeviceInstanceId = Adapter->DevInstanceID,
+ .Triggered = CreateEventW(NULL, FALSE, FALSE, NULL) };
+ if (!CreateContext.Triggered)
+ {
+ LastError = LOG_LAST_ERROR(L"Failed to create event trigger");
+ goto cleanupAdapter;
+ }
+
+ if (IsWindows7)
+ {
+ if (!CreateAdapterWin7(Adapter, Name, TunnelTypeName))
+ {
+ LastError = GetLastError();
+ goto cleanupCreateContext;
+ }
+ goto resumeAfterInstanceId;
+ }
+ SW_DEVICE_CREATE_INFO StubCreateInfo = { .cbSize = sizeof(StubCreateInfo),
+ .pszInstanceId = InstanceIdStr,
+ .pszzHardwareIds = L"",
+ .CapabilityFlags =
+ SWDeviceCapabilitiesSilentInstall | SWDeviceCapabilitiesDriverRequired,
+ .pszDeviceDescription = TunnelTypeName };
+ DEVPROPERTY StubDeviceProperties[] = { { .CompKey = { .Key = DEVPKEY_Device_ClassGuid,
+ .Store = DEVPROP_STORE_SYSTEM },
+ .Type = DEVPROP_TYPE_GUID,
+ .Buffer = (PVOID)&GUID_DEVCLASS_NET,
+ .BufferSize = sizeof(GUID_DEVCLASS_NET) } };
+ HRet = SwDeviceCreate(
+ WIREGUARD_HWID,
+ RootNodeName,
+ &StubCreateInfo,
+ _countof(StubDeviceProperties),
+ StubDeviceProperties,
+ DeviceCreateCallback,
+ &CreateContext,
+ &Adapter->SwDevice);
+ if (FAILED(HRet))
+ {
+ LastError = LOG_ERROR(HRet, L"Failed to initiate stub device creation");
+ goto cleanupCreateContext;
+ }
+ if (WaitForSingleObject(CreateContext.Triggered, INFINITE) != WAIT_OBJECT_0)
+ {
+ LastError = LOG_LAST_ERROR(L"Failed to wait for stub device creation trigger");
+ goto cleanupCreateContext;
+ }
+ if (FAILED(CreateContext.CreateResult))
+ {
+ LastError = LOG_ERROR(CreateContext.CreateResult, L"Failed to create stub device");
+ goto cleanupCreateContext;
+ }
+ DEVINST DevInst;
+ CONFIGRET CRet = CM_Locate_DevNodeW(&DevInst, Adapter->DevInstanceID, CM_LOCATE_DEVNODE_PHANTOM);
+ if (CRet != CR_SUCCESS)
+ {
+ LastError =
+ LOG_ERROR(CM_MapCrToWin32Err(CRet, ERROR_DEVICE_ENUMERATION_ERROR), L"Failed to make stub device list");
+ goto cleanupCreateContext;
+ }
+ HKEY DriverKey;
+ CRet = CM_Open_DevNode_Key(DevInst, KEY_SET_VALUE, 0, RegDisposition_OpenAlways, &DriverKey, CM_REGISTRY_SOFTWARE);
+ if (CRet != CR_SUCCESS)
+ {
+ LastError =
+ LOG_ERROR(CM_MapCrToWin32Err(CRet, ERROR_PNP_REGISTRY_ERROR), L"Failed to create software registry key");
+ goto cleanupCreateContext;
+ }
+ LastError =
+ RegSetValueExW(DriverKey, L"SuggestedInstanceId", 0, REG_BINARY, (const BYTE *)&InstanceId, sizeof(InstanceId));
+ RegCloseKey(DriverKey);
+ if (LastError != ERROR_SUCCESS)
+ {
+ LastError = LOG_ERROR(LastError, L"Failed to set SuggestedInstanceId to %s", InstanceIdStr);
+ goto cleanupCreateContext;
+ }
+ SwDeviceClose(Adapter->SwDevice);
+ Adapter->SwDevice = NULL;
+
static const WCHAR Hwids[_countof(WIREGUARD_HWID) + 1 /*Multi-string terminator*/] = WIREGUARD_HWID;
SW_DEVICE_CREATE_INFO CreateInfo = { .cbSize = sizeof(CreateInfo),
.pszInstanceId = InstanceIdStr,
.pszzHardwareIds = Hwids,
- .pszzCompatibleIds = Hwids,
.CapabilityFlags =
SWDeviceCapabilitiesSilentInstall | SWDeviceCapabilitiesDriverRequired,
.pszDeviceDescription = TunnelTypeName };
@@ -671,23 +680,6 @@ WireGuardCreateAdapter(LPCWSTR Name, LPCWSTR TunnelType, const GUID *RequestedGU
.Buffer = TunnelTypeName,
.BufferSize = (ULONG)((wcslen(TunnelTypeName) + 1) * sizeof(*TunnelTypeName)) }
};
- SW_DEVICE_CREATE_CTX CreateContext = { .DeviceInstanceId = Adapter->DevInstanceID,
- .Triggered = CreateEventW(NULL, FALSE, FALSE, NULL) };
- if (!CreateContext.Triggered)
- {
- LastError = LOG_LAST_ERROR(L"Failed to create event trigger");
- goto cleanupAdapter;
- }
-
- if (IsWindows7)
- {
- if (!CreateAdapterWin7(Adapter, Name, TunnelTypeName))
- {
- LastError = GetLastError();
- goto cleanupCreateContext;
- }
- goto resumeAfterInstanceId;
- }
HRet = SwDeviceCreate(
WIREGUARD_HWID,
@@ -783,8 +775,6 @@ resumeAfterInstanceId:
cleanupCreateContext:
CloseHandle(CreateContext.Triggered);
-cleanupInstanceIdFile:
- DeleteFileW(InstanceIdInf);
cleanupAdapter:
if (LastError != ERROR_SUCCESS)
{
@@ -818,7 +808,8 @@ WireGuardOpenAdapter(LPCWSTR Name)
if (!Adapter)
goto cleanupDeviceInstallationMutex;
- HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, WIREGUARD_ENUMERATOR, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
+ HDEVINFO DevInfo =
+ SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, WIREGUARD_ENUMERATOR, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
if (DevInfo == INVALID_HANDLE_VALUE)
{
LastError = LOG_LAST_ERROR(L"Failed to get present adapters");
diff --git a/driver/wireguard.inf b/driver/wireguard.inf
index 6abd864..ab9139e 100644
--- a/driver/wireguard.inf
+++ b/driver/wireguard.inf
@@ -30,8 +30,6 @@ wireguard.sys, , , 0x00004002 ; COPYFLG_IN_USE_RENAME | COPYFLG_NOSKIP
%WireGuard.DeviceDesc% = WireGuard.Install, WireGuard
[WireGuard.Install]
-Include = wireguard-instanceid.inf
-Needs = WireGuard.NetSetup
Characteristics = 0x1 ; NCF_VIRTUAL
AddReg = WireGuard.Ndi
AddProperty = WireGuard.Properties