]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
dco-win: factor out getting dco version
authorLev Stipakov <lev@openvpn.net>
Sun, 29 Dec 2024 14:17:59 +0000 (15:17 +0100)
committerGert Doering <gert@greenie.muc.de>
Sun, 29 Dec 2024 14:21:06 +0000 (15:21 +0100)
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 <lev@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
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 <gert@greenie.muc.de>
src/openvpn/dco_win.c

index 9224bcae3c549622de8647a279739216d505cf8f..f59bf8c42eaa65c357bb254444a925f98d605d56 100644 (file)
@@ -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