Sockets and handles are always closed even if the system call fails.
diff --git a/asio/include/asio/detail/impl/win_iocp_handle_service.ipp b/asio/include/asio/detail/impl/win_iocp_handle_service.ipp
index c12a7cd..72e7176 100644
--- a/asio/include/asio/detail/impl/win_iocp_handle_service.ipp
+++ b/asio/include/asio/detail/impl/win_iocp_handle_service.ipp
@@ -205,14 +205,20 @@
       DWORD last_error = ::GetLastError();
       ec = asio::error_code(last_error,
           asio::error::get_system_category());
-      return ec;
+    }
+    else
+    {
+      ec = asio::error_code();
     }
 
     impl.handle_ = INVALID_HANDLE_VALUE;
     impl.safe_cancellation_thread_id_ = 0;
   }
+  else
+  {
+    ec = asio::error_code();
+  }
 
-  ec = asio::error_code();
   return ec;
 }
 
diff --git a/asio/include/asio/detail/impl/win_iocp_socket_service_base.ipp b/asio/include/asio/detail/impl/win_iocp_socket_service_base.ipp
index 4d289d6..8aa4d12 100644
--- a/asio/include/asio/detail/impl/win_iocp_socket_service_base.ipp
+++ b/asio/include/asio/detail/impl/win_iocp_socket_service_base.ipp
@@ -177,15 +177,14 @@
       r->deregister_descriptor(impl.socket_, impl.reactor_data_, true);
   }
 
-  if (socket_ops::close(impl.socket_, impl.state_, false, ec) == 0)
-  {
-    impl.socket_ = invalid_socket;
-    impl.state_ = 0;
-    impl.cancel_token_.reset();
+  socket_ops::close(impl.socket_, impl.state_, false, ec);
+
+  impl.socket_ = invalid_socket;
+  impl.state_ = 0;
+  impl.cancel_token_.reset();
 #if defined(ASIO_ENABLE_CANCELIO)
-    impl.safe_cancellation_thread_id_ = 0;
+  impl.safe_cancellation_thread_id_ = 0;
 #endif // defined(ASIO_ENABLE_CANCELIO)
-  }
 
   return ec;
 }