- if(!ReadFile(device_fd, packet->data, MTU, &lenin, NULL)) {
- logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
- device, strerror(errno));
- return false;
+ ULONG status = 0;
+ DWORD len;
+ DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL);
+
+ /* Note that we don't try to cancel ongoing I/O here - we just stop listening.
+ This is because some TAP-Win32 drivers don't seem to handle cancellation very well,
+ especially when combined with other events such as the computer going to sleep - cases
+ were observed where the GetOverlappedResult() would just block indefinitely and never
+ return in that case. */
+}
+
+static void close_device(void) {
+ CancelIo(device_handle);
+
+ /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete.
+ To prevent race conditions, make sure the operation is complete
+ before we close the event it's referencing. */
+
+ DWORD len;
+
+ if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError()));