From 1d10afd3d33f5623494d9eeb2fa8237712f8aa2e Mon Sep 17 00:00:00 2001 From: Etienne Dechamps Date: Sat, 19 Jul 2014 16:05:23 +0100 Subject: [PATCH] Only read from TAP-Win32 if the device is enabled. With newer TAP-Win32 versions (such as the experimental tap-windows6 9.21.0), tinc is unable to read from the virtual network device: Error while reading from (null) {23810A13-BCA9-44CE-94C6-9AEDFBF85736}: No such file or directory This is because these new drivers apparently don't accept reads when the device is not in the connected state (media status). This commit fixes the issue by making sure we start reading no sooner than when the device is enabled, and that we stop reading when the device is disabled. This also makes the behavior somewhat cleaner, because it doesn't make much sense to read from a disabled device anyway. --- src/mingw/device.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/mingw/device.c b/src/mingw/device.c index b6dffbc9..2ef00641 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -177,12 +177,6 @@ static bool setup_device(void) { overwrite_mac = 1; } - /* Start the tap reader */ - - io_add_event(&device_read_io, device_handle_read, NULL, CreateEvent(NULL, TRUE, FALSE, NULL)); - device_read_overlapped.hEvent = device_read_io.event; - device_issue_read(); - device_info = "Windows tap device"; logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); @@ -192,22 +186,29 @@ static bool setup_device(void) { static void enable_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "Enabling %s", device_info); + ULONG status = 1; DWORD len; DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); + + io_add_event(&device_read_io, device_handle_read, NULL, CreateEvent(NULL, TRUE, FALSE, NULL)); + device_read_overlapped.hEvent = device_read_io.event; + device_issue_read(); } static void disable_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info); + + io_del(&device_read_io); + CancelIo(device_handle); + CloseHandle(device_read_overlapped.hEvent); + ULONG status = 0; DWORD len; DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); } static void close_device(void) { - io_del(&device_read_io); - CancelIo(device_handle); - CloseHandle(device_read_overlapped.hEvent); CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; free(device); device = NULL; -- 2.20.1