diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-10-07 06:28:28 +0000 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-10-11 16:12:09 +0000 |
commit | f779da4e8865526ae70214ae2b3e34f752ad6003 (patch) | |
tree | 6bbf9048f5636abdcafbf390ee377f0607183ca6 | |
parent | api: adapter: cleanup ROOT\NET enumerated devices on DLL load (diff) | |
download | wireguard-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.c | 171 | ||||
-rw-r--r-- | driver/wireguard.inf | 2 |
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 |