diff --git a/src/Makefile b/src/Makefile index b91ade8..0533910 100644 --- a/src/Makefile +++ b/src/Makefile @@ -62,7 +62,7 @@ ifeq ($(PLATFORM),windows) CC := x86_64-w64-mingw32-clang WINDRES := $(shell $(CC) $(CFLAGS) -print-prog-name=windres 2>/dev/null) CFLAGS += -Iwincompat/include -include wincompat/compat.h -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -flto -LDLIBS += -lws2_32 -lsetupapi -lole32 -ladvapi32 -Lwincompat +LDLIBS += -lws2_32 -lsetupapi -lole32 -ladvapi32 -lntdll -Lwincompat LDFLAGS += -flto -Wl,--dynamicbase -Wl,--nxcompat -Wl,--tsaware -mconsole LDFLAGS += -Wl,--major-os-version=6 -Wl,--minor-os-version=1 -Wl,--major-subsystem-version=6 -Wl,--minor-subsystem-version=1 # The use of -Wl,/delayload: here implies we're using llvm-mingw diff --git a/src/ipc-windows.h b/src/ipc-windows.h index 59fa3a9..d237fc9 100644 --- a/src/ipc-windows.h +++ b/src/ipc-windows.h @@ -19,10 +19,11 @@ static bool have_cached_kernel_interfaces; static struct hashtable cached_kernel_interfaces; static const DEVPROPKEY devpkey_name = DEVPKEY_WG_NAME; +extern bool is_win7; static int kernel_get_wireguard_interfaces(struct string_list *list) { - HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); + HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL); bool will_have_cached_kernel_interfaces = true; if (dev_info == INVALID_HANDLE_VALUE) { @@ -31,9 +32,8 @@ static int kernel_get_wireguard_interfaces(struct string_list *list) } for (DWORD i = 0;; ++i) { - bool found = false; - DWORD buf_len = 0, value_type; - WCHAR *buf = NULL, adapter_name[MAX_ADAPTER_NAME]; + DWORD buf_len; + WCHAR adapter_name[MAX_ADAPTER_NAME]; SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) }; DEVPROPTYPE prop_type; ULONG status, problem_code; @@ -46,31 +46,6 @@ static int kernel_get_wireguard_interfaces(struct string_list *list) continue; } - while (!SetupDiGetDeviceRegistryPropertyW(dev_info, &dev_info_data, SPDRP_HARDWAREID, &value_type, (BYTE *)buf, buf_len, &buf_len)) { - free(buf); - buf = NULL; - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - break; - buf = malloc(buf_len); - if (!buf) - break; - } - - if (!buf || value_type != REG_MULTI_SZ || buf_len < sizeof(*buf) * 2 || buf[buf_len / sizeof(*buf) - 1] || buf[buf_len / sizeof(*buf) - 2]) { - free(buf); - continue; - } - - for (WCHAR *item = buf; *item; item += wcslen(item) + 1) { - if (!_wcsicmp(item, L"wireguard")) { - found = true; - break; - } - } - free(buf); - if (!found) - continue; - if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name, &prop_type, (PBYTE)adapter_name, sizeof(adapter_name), NULL, 0) || @@ -155,14 +130,14 @@ err_hash: } } - dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); + dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL); if (dev_info == INVALID_HANDLE_VALUE) return NULL; for (DWORD i = 0; !interfaces; ++i) { - bool found = false; - DWORD buf_len = 0, value_type; - WCHAR *buf = NULL, adapter_name[MAX_ADAPTER_NAME]; + bool found; + DWORD buf_len; + WCHAR *buf, adapter_name[MAX_ADAPTER_NAME]; SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) }; DEVPROPTYPE prop_type; char *interface_name; @@ -173,31 +148,6 @@ err_hash: continue; } - while (!SetupDiGetDeviceRegistryPropertyW(dev_info, &dev_info_data, SPDRP_HARDWAREID, &value_type, (BYTE *)buf, buf_len, &buf_len)) { - free(buf); - buf = NULL; - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - break; - buf = malloc(buf_len); - if (!buf) - break; - } - - if (!buf || value_type != REG_MULTI_SZ || buf_len < sizeof(*buf) * 2 || buf[buf_len / sizeof(*buf) - 1] || buf[buf_len / sizeof(*buf) - 2]) { - free(buf); - continue; - } - - for (WCHAR *item = buf; *item; item += wcslen(item) + 1) { - if (!_wcsicmp(item, L"wireguard")) { - found = true; - break; - } - } - free(buf); - if (!found) - continue; - if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name, &prop_type, (PBYTE)adapter_name, sizeof(adapter_name), NULL, 0) || diff --git a/src/wincompat/init.c b/src/wincompat/init.c index f744f69..f92c0a9 100644 --- a/src/wincompat/init.c +++ b/src/wincompat/init.c @@ -10,16 +10,22 @@ #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 #endif +extern void NTAPI RtlGetNtVersionNumbers(DWORD *major, DWORD *minor, DWORD *build); +bool is_win7 = false; + __attribute__((constructor)) static void init(void) { char *colormode; - DWORD console_mode; + DWORD console_mode, major, minor; HANDLE stdout_handle; WSADATA wsaData; if (!SetDllDirectoryA("") || !SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32)) abort(); + RtlGetNtVersionNumbers(&major, &minor, NULL); + is_win7 = (major == 6 && minor <= 1) || major < 6; + WSAStartup(MAKEWORD(2, 2), &wsaData); stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // We don't close this.