From 10e785f1dcacdfd5240ac18a53f2839b4d3b979c Mon Sep 17 00:00:00 2001 From: Lev Stipakov Date: Sun, 29 Dec 2024 15:17:59 +0100 Subject: [PATCH] dco-win: factor out getting dco version As a preparation for multipeer and data_v3, add function which returns dco version in machine-readable format. Change-Id: I8e8ddd35bd3cc3334faf7f57118d1892512ae9f7 Signed-off-by: Lev Stipakov Acked-by: Gert Doering Message-Id: <20241229141800.4734-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg30297.html Signed-off-by: Gert Doering --- src/openvpn/dco_win.c | 85 +++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c index 9224bcae3..f59bf8c42 100644 --- a/src/openvpn/dco_win.c +++ b/src/openvpn/dco_win.c @@ -52,6 +52,57 @@ create_dco_handle(const char *devname, struct gc_arena *gc) return tt; } +/** + * Gets version of dco-win driver + * + * Fills Major/Minor/Patch fields in a passed OVPN_VERSION + * struct. If version cannot be obtained, fields are set to 0. + * + * @param version pointer to OVPN_VERSION struct + * @returns true if version has been obtained, false otherwise + */ +static bool +dco_get_version(OVPN_VERSION *version) +{ + CLEAR(*version); + + bool res = false; + + HANDLE h = CreateFile("\\\\.\\ovpn-dco-ver", GENERIC_READ, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (h == INVALID_HANDLE_VALUE) + { + /* fallback to a "normal" device, this will fail if device is already in use */ + h = CreateFile("\\\\.\\ovpn-dco", GENERIC_READ, + 0, NULL, OPEN_EXISTING, 0, NULL); + } + + if (h == INVALID_HANDLE_VALUE) + { + goto done; + } + + DWORD bytes_returned = 0; + if (!DeviceIoControl(h, OVPN_IOCTL_GET_VERSION, NULL, 0, + version, sizeof(*version), &bytes_returned, NULL)) + { + goto done; + } + + res = true; + +done: + if (h != INVALID_HANDLE_VALUE) + { + CloseHandle(h); + } + + msg(D_DCO_DEBUG, "dco version: %ld.%ld.%ld", version->Major, version->Minor, version->Patch); + + return res; +} + bool ovpn_dco_init(int mode, dco_context_t *dco) { @@ -386,39 +437,17 @@ dco_available(int msglevel) const char * dco_version_string(struct gc_arena *gc) { - OVPN_VERSION version; - ZeroMemory(&version, sizeof(OVPN_VERSION)); - - /* first, try a non-exclusive control device, available from 1.3.0 */ - HANDLE h = CreateFile("\\\\.\\ovpn-dco-ver", GENERIC_READ, - 0, NULL, OPEN_EXISTING, 0, NULL); - - if (h == INVALID_HANDLE_VALUE) + OVPN_VERSION version = {0}; + if (dco_get_version(&version)) { - /* fallback to a "normal" device, this will fail if device is already in use */ - h = CreateFile("\\\\.\\ovpn-dco", GENERIC_READ, - 0, NULL, OPEN_EXISTING, 0, NULL); + struct buffer out = alloc_buf_gc(256, gc); + buf_printf(&out, "%ld.%ld.%ld", version.Major, version.Minor, version.Patch); + return BSTR(&out); } - - if (h == INVALID_HANDLE_VALUE) - { - return "N/A"; - } - - DWORD bytes_returned = 0; - if (!DeviceIoControl(h, OVPN_IOCTL_GET_VERSION, NULL, 0, - &version, sizeof(version), &bytes_returned, NULL)) + else { - CloseHandle(h); return "N/A"; } - - CloseHandle(h); - - struct buffer out = alloc_buf_gc(256, gc); - buf_printf(&out, "%ld.%ld.%ld", version.Major, version.Minor, version.Patch); - - return BSTR(&out); } int