/*
 * Support for overlapped IO
 *
 * Some code borrowed from Modules/_winapi.c of CPython
 */

/* XXX check overflow and DWORD <-> Py_ssize_t conversions
   Check itemsize */

#include "Python.h"
#include "structmember.h"         // PyMemberDef

#define WINDOWS_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mswsock.h>

#if defined(MS_WIN32) && !defined(MS_WIN64)
#  define F_POINTER "k"
#  define T_POINTER T_ULONG
#else
#  define F_POINTER "K"
#  define T_POINTER T_ULONGLONG
#endif

#define F_HANDLE F_POINTER
#define F_ULONG_PTR F_POINTER
#define F_DWORD "k"
#define F_BOOL "i"
#define F_UINT "I"

#define T_HANDLE T_POINTER

/*[python input]
class OVERLAPPED_converter(CConverter):
    type = 'OVERLAPPED *'
    format_unit = '"F_POINTER"'

class HANDLE_converter(CConverter):
    type = 'HANDLE'
    format_unit = '"F_HANDLE"'

class ULONG_PTR_converter(CConverter):
    type = 'ULONG_PTR'
    format_unit = '"F_ULONG_PTR"'

class DWORD_converter(CConverter):
    type = 'DWORD'
    format_unit = 'k'

class BOOL_converter(CConverter):
    type = 'BOOL'
    format_unit = 'i'
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=83bb8c2c2514f2a8]*/

/*[clinic input]
module _overlapped
class _overlapped.Overlapped "OverlappedObject *" "&OverlappedType"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92e5a799db35b96c]*/


enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE,
      TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE,
      TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM,
      TYPE_WRITE_TO, TYPE_READ_FROM_INTO};

typedef struct {
    PyObject_HEAD
    OVERLAPPED overlapped;
    /* For convenience, we store the file handle too */
    HANDLE handle;
    /* Error returned by last method call */
    DWORD error;
    /* Type of operation */
    DWORD type;
    union {
        /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */
        PyObject *allocated_buffer;
        /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */
        Py_buffer user_buffer;

        /* Data used for reading from a connectionless socket:
           TYPE_READ_FROM */
        struct {
            // A (buffer, (host, port)) tuple
            PyObject *result;
            // The actual read buffer
            PyObject *allocated_buffer;
            struct sockaddr_in6 address;
            int address_length;
        } read_from;

        /* Data used for reading from a connectionless socket:
           TYPE_READ_FROM_INTO */
        struct {
            // A (number of bytes read, (host, port)) tuple
            PyObject* result;
            /* Buffer passed by the user */
            Py_buffer user_buffer;
            struct sockaddr_in6 address;
            int address_length;
        } read_from_into;
    };
} OverlappedObject;

typedef struct {
    PyTypeObject *overlapped_type;
} OverlappedState;

static inline OverlappedState*
overlapped_get_state(PyObject *module)
{
    void *state = PyModule_GetState(module);
    assert(state != NULL);
    return (OverlappedState *)state;
}


static inline void
steal_buffer(Py_buffer * dst, Py_buffer * src)
{
    memcpy(dst, src, sizeof(Py_buffer));
    memset(src, 0, sizeof(Py_buffer));
}

/*
 * Map Windows error codes to subclasses of OSError
 */

static PyObject *
SetFromWindowsErr(DWORD err)
{
    PyObject *exception_type;

    if (err == 0)
        err = GetLastError();
    switch (err) {
        case ERROR_CONNECTION_REFUSED:
            exception_type = PyExc_ConnectionRefusedError;
            break;
        case ERROR_CONNECTION_ABORTED:
            exception_type = PyExc_ConnectionAbortedError;
            break;
        default:
            exception_type = PyExc_OSError;
    }
    return PyErr_SetExcFromWindowsErr(exception_type, err);
}

/*
 * Some functions should be loaded at runtime
 */

static LPFN_ACCEPTEX Py_AcceptEx = NULL;
static LPFN_CONNECTEX Py_ConnectEx = NULL;
static LPFN_DISCONNECTEX Py_DisconnectEx = NULL;
static LPFN_TRANSMITFILE Py_TransmitFile = NULL;

#define GET_WSA_POINTER(s, x)                                           \
    (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,    \
                              &Guid##x, sizeof(Guid##x), &Py_##x,       \
                              sizeof(Py_##x), &dwBytes, NULL, NULL))

static int
initialize_function_pointers(void)
{
    GUID GuidAcceptEx = WSAID_ACCEPTEX;
    GUID GuidConnectEx = WSAID_CONNECTEX;
    GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
    GUID GuidTransmitFile = WSAID_TRANSMITFILE;
    SOCKET s;
    DWORD dwBytes;

    if (Py_AcceptEx != NULL &&
        Py_ConnectEx != NULL &&
        Py_DisconnectEx != NULL &&
        Py_TransmitFile != NULL)
    {
        // All function pointers are initialized already
        // by previous module import
        return 0;
    }

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET) {
        SetFromWindowsErr(WSAGetLastError());
        return -1;
    }

    if (!GET_WSA_POINTER(s, AcceptEx) ||
        !GET_WSA_POINTER(s, ConnectEx) ||
        !GET_WSA_POINTER(s, DisconnectEx) ||
        !GET_WSA_POINTER(s, TransmitFile))
    {
        closesocket(s);
        SetFromWindowsErr(WSAGetLastError());
        return -1;
    }

    closesocket(s);
    return 0;
}

/*
 * Completion port stuff
 */

/*[clinic input]
_overlapped.CreateIoCompletionPort

    handle as FileHandle: HANDLE
    port as ExistingCompletionPort: HANDLE
    key as CompletionKey: ULONG_PTR
    concurrency as NumberOfConcurrentThreads: DWORD
    /

Create a completion port or register a handle with a port.
[clinic start generated code]*/

static PyObject *
_overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle,
                                        HANDLE ExistingCompletionPort,
                                        ULONG_PTR CompletionKey,
                                        DWORD NumberOfConcurrentThreads)
/*[clinic end generated code: output=24ede2b0f05e5433 input=847bae4d0efe1976]*/
{
    HANDLE ret;

    Py_BEGIN_ALLOW_THREADS
    ret = CreateIoCompletionPort(FileHandle, ExistingCompletionPort,
                                 CompletionKey, NumberOfConcurrentThreads);
    Py_END_ALLOW_THREADS

    if (ret == NULL)
        return SetFromWindowsErr(0);
    return Py_BuildValue(F_HANDLE, ret);
}

/*[clinic input]
_overlapped.GetQueuedCompletionStatus

    port as CompletionPort: HANDLE
    msecs as Milliseconds: DWORD
    /

Get a message from completion port.

Wait for up to msecs milliseconds.
[clinic start generated code]*/

static PyObject *
_overlapped_GetQueuedCompletionStatus_impl(PyObject *module,
                                           HANDLE CompletionPort,
                                           DWORD Milliseconds)
/*[clinic end generated code: output=68314171628dddb7 input=94a042d14c4f6410]*/
{
    DWORD NumberOfBytes = 0;
    ULONG_PTR CompletionKey = 0;
    OVERLAPPED *Overlapped = NULL;
    DWORD err;
    BOOL ret;

    Py_BEGIN_ALLOW_THREADS
    ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes,
                                    &CompletionKey, &Overlapped, Milliseconds);
    Py_END_ALLOW_THREADS

    err = ret ? ERROR_SUCCESS : GetLastError();
    if (Overlapped == NULL) {
        if (err == WAIT_TIMEOUT)
            Py_RETURN_NONE;
        else
            return SetFromWindowsErr(err);
    }
    return Py_BuildValue(F_DWORD F_DWORD F_ULONG_PTR F_POINTER,
                         err, NumberOfBytes, CompletionKey, Overlapped);
}

/*[clinic input]
_overlapped.PostQueuedCompletionStatus

    port as CompletionPort: HANDLE
    bytes as NumberOfBytes: DWORD
    key as CompletionKey: ULONG_PTR
    address as Overlapped: OVERLAPPED
    /

Post a message to completion port.
[clinic start generated code]*/

static PyObject *
_overlapped_PostQueuedCompletionStatus_impl(PyObject *module,
                                            HANDLE CompletionPort,
                                            DWORD NumberOfBytes,
                                            ULONG_PTR CompletionKey,
                                            OVERLAPPED *Overlapped)
/*[clinic end generated code: output=93e73f2933a43e9e input=e936202d87937aca]*/
{
    BOOL ret;

    Py_BEGIN_ALLOW_THREADS
    ret = PostQueuedCompletionStatus(CompletionPort, NumberOfBytes,
                                     CompletionKey, Overlapped);
    Py_END_ALLOW_THREADS

    if (!ret)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}

/*
 * Wait for a handle
 */

struct PostCallbackData {
    HANDLE CompletionPort;
    LPOVERLAPPED Overlapped;
};

static VOID CALLBACK
PostToQueueCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    struct PostCallbackData *p = (struct PostCallbackData*) lpParameter;

    PostQueuedCompletionStatus(p->CompletionPort, TimerOrWaitFired,
                               0, p->Overlapped);
    /* ignore possible error! */
    PyMem_RawFree(p);
}

/*[clinic input]
_overlapped.RegisterWaitWithQueue

    Object: HANDLE
    CompletionPort: HANDLE
    Overlapped: OVERLAPPED
    Timeout as Milliseconds: DWORD
    /

Register wait for Object; when complete CompletionPort is notified.
[clinic start generated code]*/

static PyObject *
_overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object,
                                       HANDLE CompletionPort,
                                       OVERLAPPED *Overlapped,
                                       DWORD Milliseconds)
/*[clinic end generated code: output=c2ace732e447fe45 input=2dd4efee44abe8ee]*/
{
    HANDLE NewWaitObject;
    struct PostCallbackData data = {CompletionPort, Overlapped}, *pdata;

    /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since
       PostToQueueCallback() will call PyMem_Free() from a new C thread
       which doesn't hold the GIL. */
    pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData));
    if (pdata == NULL)
        return SetFromWindowsErr(0);

    *pdata = data;

    if (!RegisterWaitForSingleObject(
            &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds,
            WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE))
    {
        SetFromWindowsErr(0);
        PyMem_RawFree(pdata);
        return NULL;
    }

    return Py_BuildValue(F_HANDLE, NewWaitObject);
}

/*[clinic input]
_overlapped.UnregisterWait

    WaitHandle: HANDLE
    /

Unregister wait handle.
[clinic start generated code]*/

static PyObject *
_overlapped_UnregisterWait_impl(PyObject *module, HANDLE WaitHandle)
/*[clinic end generated code: output=ec90cd955a9a617d input=a56709544cb2df0f]*/
{
    BOOL ret;

    Py_BEGIN_ALLOW_THREADS
    ret = UnregisterWait(WaitHandle);
    Py_END_ALLOW_THREADS

    if (!ret)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}

/*[clinic input]
_overlapped.UnregisterWaitEx

    WaitHandle: HANDLE
    Event: HANDLE
    /

Unregister wait handle.
[clinic start generated code]*/

static PyObject *
_overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle,
                                  HANDLE Event)
/*[clinic end generated code: output=2e3d84c1d5f65b92 input=953cddc1de50fab9]*/
{
    BOOL ret;

    Py_BEGIN_ALLOW_THREADS
    ret = UnregisterWaitEx(WaitHandle, Event);
    Py_END_ALLOW_THREADS

    if (!ret)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}

/*
 * Event functions -- currently only used by tests
 */

/*[clinic input]
_overlapped.CreateEvent

    EventAttributes: object
    ManualReset: BOOL
    InitialState: BOOL
    Name: Py_UNICODE(accept={str, NoneType})
    /

Create an event.

EventAttributes must be None.
[clinic start generated code]*/

static PyObject *
_overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes,
                             BOOL ManualReset, BOOL InitialState,
                             const Py_UNICODE *Name)
/*[clinic end generated code: output=8e04f0916c17b13d input=dbc36ae14375ba24]*/
{
    HANDLE Event;

    if (EventAttributes != Py_None) {
        PyErr_SetString(PyExc_ValueError, "EventAttributes must be None");
        return NULL;
    }

    Py_BEGIN_ALLOW_THREADS
    Event = CreateEventW(NULL, ManualReset, InitialState, Name);
    Py_END_ALLOW_THREADS

    if (Event == NULL)
        return SetFromWindowsErr(0);
    return Py_BuildValue(F_HANDLE, Event);
}

/*[clinic input]
_overlapped.SetEvent

    Handle: HANDLE
    /

Set event.
[clinic start generated code]*/

static PyObject *
_overlapped_SetEvent_impl(PyObject *module, HANDLE Handle)
/*[clinic end generated code: output=5b8d974216b0e569 input=d8b0d26eb7391e80]*/
{
    BOOL ret;

    Py_BEGIN_ALLOW_THREADS
    ret = SetEvent(Handle);
    Py_END_ALLOW_THREADS

    if (!ret)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}

/*[clinic input]
_overlapped.ResetEvent

    Handle: HANDLE
    /

Reset event.
[clinic start generated code]*/

static PyObject *
_overlapped_ResetEvent_impl(PyObject *module, HANDLE Handle)
/*[clinic end generated code: output=066537a8405cddb2 input=d4e089c9ba84ff2f]*/
{
    BOOL ret;

    Py_BEGIN_ALLOW_THREADS
    ret = ResetEvent(Handle);
    Py_END_ALLOW_THREADS

    if (!ret)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}

/*
 * Bind socket handle to local port without doing slow getaddrinfo()
 */

/*[clinic input]
_overlapped.BindLocal

    handle as Socket: HANDLE
    family as Family: int
    /

Bind a socket handle to an arbitrary local port.

family should be AF_INET or AF_INET6.
[clinic start generated code]*/

static PyObject *
_overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family)
/*[clinic end generated code: output=edb93862697aed9c input=a0e7b5c2f541170c]*/
{
    BOOL ret;

    if (Family == AF_INET) {
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = 0;
        addr.sin_addr.S_un.S_addr = INADDR_ANY;
        ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr))
                != SOCKET_ERROR;
    } else if (Family == AF_INET6) {
        struct sockaddr_in6 addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin6_family = AF_INET6;
        addr.sin6_port = 0;
        addr.sin6_addr = in6addr_any;
        ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr))
                != SOCKET_ERROR;
    } else {
        PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4");
        return NULL;
    }

    if (!ret)
        return SetFromWindowsErr(WSAGetLastError());
    Py_RETURN_NONE;
}

/*
 * Windows equivalent of os.strerror() -- compare _ctypes/callproc.c
 */

/*[clinic input]
_overlapped.FormatMessage

    error_code as code: DWORD
    /

Return error message for an error code.
[clinic start generated code]*/

static PyObject *
_overlapped_FormatMessage_impl(PyObject *module, DWORD code)
/*[clinic end generated code: output=02c964ff22407c6b input=644bb5b80326179e]*/
{
    DWORD n;
    WCHAR *lpMsgBuf;
    PyObject *res;

    n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                       FORMAT_MESSAGE_FROM_SYSTEM |
                       FORMAT_MESSAGE_IGNORE_INSERTS,
                       NULL,
                       code,
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                       (LPWSTR) &lpMsgBuf,
                       0,
                       NULL);
    if (n) {
        while (iswspace(lpMsgBuf[n-1]))
            --n;
        lpMsgBuf[n] = L'\0';
        res = Py_BuildValue("u", lpMsgBuf);
    } else {
        res = PyUnicode_FromFormat("unknown error code %u", code);
    }
    LocalFree(lpMsgBuf);
    return res;
}


/*
 * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE
 */

static inline void
mark_as_completed(OVERLAPPED *ov)
{
    ov->Internal = 0;
    if (ov->hEvent != NULL)
        SetEvent(ov->hEvent);
}

/*
 * A Python object wrapping an OVERLAPPED structure and other useful data
 * for overlapped I/O
 */

/*[clinic input]
@classmethod
_overlapped.Overlapped.__new__

    event: HANDLE(c_default='INVALID_HANDLE_VALUE') = _overlapped.INVALID_HANDLE_VALUE

OVERLAPPED structure wrapper.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event)
/*[clinic end generated code: output=6da60504a18eb421 input=26b8a7429e629e95]*/
{
    OverlappedObject *self;

    if (event == INVALID_HANDLE_VALUE) {
        event = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (event == NULL)
            return SetFromWindowsErr(0);
    }

    self = PyObject_New(OverlappedObject, type);
    if (self == NULL) {
        if (event != NULL)
            CloseHandle(event);
        return NULL;
    }

    self->handle = NULL;
    self->error = 0;
    self->type = TYPE_NONE;
    self->allocated_buffer = NULL;
    memset(&self->overlapped, 0, sizeof(OVERLAPPED));
    memset(&self->user_buffer, 0, sizeof(Py_buffer));
    if (event)
        self->overlapped.hEvent = event;
    return (PyObject *)self;
}


/* Note (bpo-32710): OverlappedType.tp_clear is not defined to not release
   buffers while overlapped are still running, to prevent a crash. */
static int
Overlapped_clear(OverlappedObject *self)
{
    switch (self->type) {
        case TYPE_READ:
        case TYPE_ACCEPT: {
            Py_CLEAR(self->allocated_buffer);
            break;
        }
        case TYPE_READ_FROM: {
            // An initial call to WSARecvFrom will only allocate the buffer.
            // The result tuple of (message, address) is only
            // allocated _after_ a message has been received.
            if(self->read_from.result) {
                // We've received a message, free the result tuple.
                Py_CLEAR(self->read_from.result);
            }
            if(self->read_from.allocated_buffer) {
                Py_CLEAR(self->read_from.allocated_buffer);
            }
            break;
        }
        case TYPE_READ_FROM_INTO: {
            if (self->read_from_into.result) {
                // We've received a message, free the result tuple.
                Py_CLEAR(self->read_from_into.result);
            }
            if (self->read_from_into.user_buffer.obj) {
                PyBuffer_Release(&self->read_from_into.user_buffer);
            }
            break;
        }
        case TYPE_WRITE:
        case TYPE_WRITE_TO:
        case TYPE_READINTO: {
            if (self->user_buffer.obj) {
                PyBuffer_Release(&self->user_buffer);
            }
            break;
        }
    }
    self->type = TYPE_NOT_STARTED;
    return 0;
}

static void
Overlapped_dealloc(OverlappedObject *self)
{
    DWORD bytes;
    DWORD olderr = GetLastError();
    BOOL wait = FALSE;
    BOOL ret;

    if (!HasOverlappedIoCompleted(&self->overlapped) &&
        self->type != TYPE_NOT_STARTED)
    {
        // NOTE: We should not get here, if we do then something is wrong in
        // the IocpProactor or ProactorEventLoop. Since everything uses IOCP if
        // the overlapped IO hasn't completed yet then we should not be
        // deallocating!
        //
        // The problem is likely that this OverlappedObject was removed from
        // the IocpProactor._cache before it was complete. The _cache holds a
        // reference while IO is pending so that it does not get deallocated
        // while the kernel has retained the OVERLAPPED structure.
        //
        // CancelIoEx (likely called from self.cancel()) may have successfully
        // completed, but the OVERLAPPED is still in use until either
        // HasOverlappedIoCompleted() is true or GetQueuedCompletionStatus has
        // returned this OVERLAPPED object.
        //
        // NOTE: Waiting when IOCP is in use can hang indefinitely, but this
        // CancelIoEx is superfluous in that self.cancel() was already called,
        // so I've only ever seen this return FALSE with GLE=ERROR_NOT_FOUND
        Py_BEGIN_ALLOW_THREADS
        if (CancelIoEx(self->handle, &self->overlapped))
            wait = TRUE;

        ret = GetOverlappedResult(self->handle, &self->overlapped,
                                  &bytes, wait);
        Py_END_ALLOW_THREADS

        switch (ret ? ERROR_SUCCESS : GetLastError()) {
            case ERROR_SUCCESS:
            case ERROR_NOT_FOUND:
            case ERROR_OPERATION_ABORTED:
                break;
            default:
                PyErr_Format(
                    PyExc_RuntimeError,
                    "%R still has pending operation at "
                    "deallocation, the process may crash", self);
                PyErr_WriteUnraisable(NULL);
        }
    }

    if (self->overlapped.hEvent != NULL) {
        CloseHandle(self->overlapped.hEvent);
    }

    Overlapped_clear(self);
    SetLastError(olderr);

    PyTypeObject *tp = Py_TYPE(self);
    PyObject_Free(self);
    Py_DECREF(tp);
}


/* Convert IPv4 sockaddr to a Python str. */

static PyObject *
make_ipv4_addr(const struct sockaddr_in *addr)
{
        char buf[INET_ADDRSTRLEN];
        if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) {
                PyErr_SetFromErrno(PyExc_OSError);
                return NULL;
        }
        return PyUnicode_FromString(buf);
}

/* Convert IPv6 sockaddr to a Python str. */

static PyObject *
make_ipv6_addr(const struct sockaddr_in6 *addr)
{
        char buf[INET6_ADDRSTRLEN];
        if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) {
                PyErr_SetFromErrno(PyExc_OSError);
                return NULL;
        }
        return PyUnicode_FromString(buf);
}

static PyObject*
unparse_address(LPSOCKADDR Address, DWORD Length)
{
        /* The function is adopted from mocketmodule.c makesockaddr()*/

    switch(Address->sa_family) {
        case AF_INET: {
            const struct sockaddr_in *a = (const struct sockaddr_in *)Address;
            PyObject *addrobj = make_ipv4_addr(a);
            PyObject *ret = NULL;
            if (addrobj) {
                ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
                Py_DECREF(addrobj);
            }
            return ret;
        }
        case AF_INET6: {
            const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)Address;
            PyObject *addrobj = make_ipv6_addr(a);
            PyObject *ret = NULL;
            if (addrobj) {
                ret = Py_BuildValue("OiII",
                                    addrobj,
                                    ntohs(a->sin6_port),
                                    ntohl(a->sin6_flowinfo),
                                    a->sin6_scope_id);
                Py_DECREF(addrobj);
            }
            return ret;
        }
        default: {
            PyErr_SetString(PyExc_ValueError, "recvfrom returned unsupported address family");
            return NULL;
        }
    }
}

/*[clinic input]
_overlapped.Overlapped.cancel

Cancel overlapped operation.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_cancel_impl(OverlappedObject *self)
/*[clinic end generated code: output=54ad7aeece89901c input=80eb67c7b57dbcf1]*/
{
    BOOL ret = TRUE;

    if (self->type == TYPE_NOT_STARTED
        || self->type == TYPE_WAIT_NAMED_PIPE_AND_CONNECT)
        Py_RETURN_NONE;

    if (!HasOverlappedIoCompleted(&self->overlapped)) {
        Py_BEGIN_ALLOW_THREADS
        ret = CancelIoEx(self->handle, &self->overlapped);
        Py_END_ALLOW_THREADS
    }

    /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */
    if (!ret && GetLastError() != ERROR_NOT_FOUND)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}

/*[clinic input]
_overlapped.Overlapped.getresult

    wait: BOOL(c_default='FALSE') = False
    /

Retrieve result of operation.

If wait is true then it blocks until the operation is finished.  If wait
is false and the operation is still pending then an error is raised.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait)
/*[clinic end generated code: output=8c9bd04d08994f6c input=aa5b03e9897ca074]*/
{
    DWORD transferred = 0;
    BOOL ret;
    DWORD err;
    PyObject *addr;

    if (self->type == TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation not yet attempted");
        return NULL;
    }

    if (self->type == TYPE_NOT_STARTED) {
        PyErr_SetString(PyExc_ValueError, "operation failed to start");
        return NULL;
    }

    Py_BEGIN_ALLOW_THREADS
    ret = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
                              wait);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_MORE_DATA:
            break;
        case ERROR_BROKEN_PIPE:
            if (self->type == TYPE_READ || self->type == TYPE_READINTO) {
                break;
            }
            else if (self->type == TYPE_READ_FROM &&
                     (self->read_from.result != NULL ||
                      self->read_from.allocated_buffer != NULL))
            {
                break;
            }
            else if (self->type == TYPE_READ_FROM_INTO &&
                     self->read_from_into.result != NULL)
            {
                break;
            }
            /* fall through */
        default:
            return SetFromWindowsErr(err);
    }

    switch (self->type) {
        case TYPE_READ:
            assert(PyBytes_CheckExact(self->allocated_buffer));
            if (transferred != PyBytes_GET_SIZE(self->allocated_buffer) &&
                _PyBytes_Resize(&self->allocated_buffer, transferred))
                return NULL;

            Py_INCREF(self->allocated_buffer);
            return self->allocated_buffer;
        case TYPE_READ_FROM:
            assert(PyBytes_CheckExact(self->read_from.allocated_buffer));

            if (transferred != PyBytes_GET_SIZE(
                    self->read_from.allocated_buffer) &&
                _PyBytes_Resize(&self->read_from.allocated_buffer, transferred))
            {
                return NULL;
            }

            // unparse the address
            addr = unparse_address((SOCKADDR*)&self->read_from.address,
                                   self->read_from.address_length);

            if (addr == NULL) {
                return NULL;
            }

            // The result is a two item tuple: (message, address)
            self->read_from.result = PyTuple_New(2);
            if (self->read_from.result == NULL) {
                Py_CLEAR(addr);
                return NULL;
            }

            // first item: message
            Py_INCREF(self->read_from.allocated_buffer);
            PyTuple_SET_ITEM(self->read_from.result, 0,
                             self->read_from.allocated_buffer);
            // second item: address
            PyTuple_SET_ITEM(self->read_from.result, 1, addr);

            Py_INCREF(self->read_from.result);
            return self->read_from.result;
        case TYPE_READ_FROM_INTO:
            // unparse the address
            addr = unparse_address((SOCKADDR*)&self->read_from_into.address,
                self->read_from_into.address_length);

            if (addr == NULL) {
                return NULL;
            }

            // The result is a two item tuple: (number of bytes read, address)
            self->read_from_into.result = PyTuple_New(2);
            if (self->read_from_into.result == NULL) {
                Py_CLEAR(addr);
                return NULL;
            }

            // first item: number of bytes read
            PyTuple_SET_ITEM(self->read_from_into.result, 0,
                PyLong_FromUnsignedLong((unsigned long)transferred));
            // second item: address
            PyTuple_SET_ITEM(self->read_from_into.result, 1, addr);

            Py_INCREF(self->read_from_into.result);
            return self->read_from_into.result;
        default:
            return PyLong_FromUnsignedLong((unsigned long) transferred);
    }
}

static PyObject *
do_ReadFile(OverlappedObject *self, HANDLE handle,
            char *bufstart, DWORD buflen)
{
    DWORD nread;
    int ret;
    DWORD err;

    Py_BEGIN_ALLOW_THREADS
    ret = ReadFile(handle, bufstart, buflen, &nread,
                   &self->overlapped);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
    switch (err) {
        case ERROR_BROKEN_PIPE:
            mark_as_completed(&self->overlapped);
            return SetFromWindowsErr(err);
        case ERROR_SUCCESS:
        case ERROR_MORE_DATA:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}

/*[clinic input]
_overlapped.Overlapped.ReadFile

    handle: HANDLE
    size: DWORD
    /

Start overlapped read.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle,
                                     DWORD size)
/*[clinic end generated code: output=4c8557e16941e4ae input=98c495baa0342425]*/
{
    PyObject *buf;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T <= SIZEOF_LONG
    size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
#endif
    buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
    if (buf == NULL)
        return NULL;

    self->type = TYPE_READ;
    self->handle = handle;
    self->allocated_buffer = buf;

    return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size);
}

/*[clinic input]
_overlapped.Overlapped.ReadFileInto

    handle: HANDLE
    buf as bufobj: Py_buffer
    /

Start overlapped receive.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self,
                                         HANDLE handle, Py_buffer *bufobj)
/*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/
{
    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T > SIZEOF_LONG
    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
        PyErr_SetString(PyExc_ValueError, "buffer too large");
        return NULL;
    }
#endif
    steal_buffer(&self->user_buffer, bufobj);

    self->type = TYPE_READINTO;
    self->handle = handle;

    return do_ReadFile(self, handle, self->user_buffer.buf,
                       (DWORD)self->user_buffer.len);
}

static PyObject *
do_WSARecv(OverlappedObject *self, HANDLE handle,
           char *bufstart, DWORD buflen, DWORD flags)
{
    DWORD nread;
    WSABUF wsabuf;
    int ret;
    DWORD err;

    wsabuf.buf = bufstart;
    wsabuf.len = buflen;

    Py_BEGIN_ALLOW_THREADS
    ret = WSARecv((SOCKET)handle, &wsabuf, 1, &nread, &flags,
                  &self->overlapped, NULL);
    Py_END_ALLOW_THREADS

    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
    switch (err) {
        case ERROR_BROKEN_PIPE:
            mark_as_completed(&self->overlapped);
            return SetFromWindowsErr(err);
        case ERROR_SUCCESS:
        case ERROR_MORE_DATA:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}


/*[clinic input]
_overlapped.Overlapped.WSARecv

    handle: HANDLE
    size: DWORD
    flags: DWORD = 0
    /

Start overlapped receive.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle,
                                    DWORD size, DWORD flags)
/*[clinic end generated code: output=3a5e9c61ff040906 input=8c04e506cc3d741a]*/
{
    PyObject *buf;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T <= SIZEOF_LONG
    size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
#endif
    buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
    if (buf == NULL)
        return NULL;

    self->type = TYPE_READ;
    self->handle = handle;
    self->allocated_buffer = buf;

    return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags);
}

/*[clinic input]
_overlapped.Overlapped.WSARecvInto

    handle: HANDLE
    buf as bufobj: Py_buffer
    flags: DWORD
    /

Start overlapped receive.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
                                        HANDLE handle, Py_buffer *bufobj,
                                        DWORD flags)
/*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/
{
    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T > SIZEOF_LONG
    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
        PyErr_SetString(PyExc_ValueError, "buffer too large");
        return NULL;
    }
#endif
    steal_buffer(&self->user_buffer, bufobj);

    self->type = TYPE_READINTO;
    self->handle = handle;

    return do_WSARecv(self, handle, self->user_buffer.buf,
                      (DWORD)self->user_buffer.len, flags);
}

/*[clinic input]
_overlapped.Overlapped.WriteFile

    handle: HANDLE
    buf as bufobj: Py_buffer
    /

Start overlapped write.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
                                      Py_buffer *bufobj)
/*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/
{
    DWORD written;
    BOOL ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T > SIZEOF_LONG
    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
        PyErr_SetString(PyExc_ValueError, "buffer too large");
        return NULL;
    }
#endif
    steal_buffer(&self->user_buffer, bufobj);

    self->type = TYPE_WRITE;
    self->handle = handle;

    Py_BEGIN_ALLOW_THREADS
    ret = WriteFile(handle, self->user_buffer.buf,
                    (DWORD)self->user_buffer.len,
                    &written, &self->overlapped);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}

/*[clinic input]
_overlapped.Overlapped.WSASend

    handle: HANDLE
    buf as bufobj: Py_buffer
    flags: DWORD
    /

Start overlapped send.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
                                    Py_buffer *bufobj, DWORD flags)
/*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/
{
    DWORD written;
    WSABUF wsabuf;
    int ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T > SIZEOF_LONG
    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
        PyErr_SetString(PyExc_ValueError, "buffer too large");
        return NULL;
    }
#endif
    steal_buffer(&self->user_buffer, bufobj);

    self->type = TYPE_WRITE;
    self->handle = handle;
    wsabuf.len = (DWORD)self->user_buffer.len;
    wsabuf.buf = self->user_buffer.buf;

    Py_BEGIN_ALLOW_THREADS
    ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags,
                  &self->overlapped, NULL);
    Py_END_ALLOW_THREADS

    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}

/*[clinic input]
_overlapped.Overlapped.AcceptEx

    listen_handle as ListenSocket: HANDLE
    accept_handle as AcceptSocket: HANDLE
    /

Start overlapped wait for client to connect.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self,
                                     HANDLE ListenSocket,
                                     HANDLE AcceptSocket)
/*[clinic end generated code: output=9a7381d4232af889 input=b83473224fc3a1c5]*/
{
    DWORD BytesReceived;
    DWORD size;
    PyObject *buf;
    BOOL ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

    size = sizeof(struct sockaddr_in6) + 16;
    buf = PyBytes_FromStringAndSize(NULL, size*2);
    if (!buf)
        return NULL;

    self->type = TYPE_ACCEPT;
    self->handle = ListenSocket;
    self->allocated_buffer = buf;

    Py_BEGIN_ALLOW_THREADS
    ret = Py_AcceptEx((SOCKET)ListenSocket, (SOCKET)AcceptSocket,
                      PyBytes_AS_STRING(buf), 0, size, size, &BytesReceived,
                      &self->overlapped);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}


static int
parse_address(PyObject *obj, SOCKADDR *Address, int Length)
{
    PyObject *Host_obj;
    Py_UNICODE *Host;
    unsigned short Port;
    unsigned long FlowInfo;
    unsigned long ScopeId;

    memset(Address, 0, Length);

    switch (PyTuple_GET_SIZE(obj)) {
    case 2: {
        if (!PyArg_ParseTuple(obj, "UH", &Host_obj, &Port)) {
            return -1;
        }
#if USE_UNICODE_WCHAR_CACHE
        Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj);
#else /* USE_UNICODE_WCHAR_CACHE */
        Host = PyUnicode_AsWideCharString(Host_obj, NULL);
#endif /* USE_UNICODE_WCHAR_CACHE */
        if (Host == NULL) {
            return -1;
        }
        Address->sa_family = AF_INET;
        if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) {
            SetFromWindowsErr(WSAGetLastError());
            Length = -1;
        }
        else {
            ((SOCKADDR_IN*)Address)->sin_port = htons(Port);
        }
#if !USE_UNICODE_WCHAR_CACHE
        PyMem_Free(Host);
#endif /* USE_UNICODE_WCHAR_CACHE */
        return Length;
    }
    case 4: {
        if (!PyArg_ParseTuple(obj,
                "UHkk;ConnectEx(): illegal address_as_bytes argument",
                &Host_obj, &Port, &FlowInfo, &ScopeId))
        {
            return -1;
        }
#if USE_UNICODE_WCHAR_CACHE
        Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj);
#else /* USE_UNICODE_WCHAR_CACHE */
        Host = PyUnicode_AsWideCharString(Host_obj, NULL);
#endif /* USE_UNICODE_WCHAR_CACHE */
        if (Host == NULL) {
            return -1;
        }
        Address->sa_family = AF_INET6;
        if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) {
            SetFromWindowsErr(WSAGetLastError());
            Length = -1;
        }
        else {
            ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port);
            ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo;
            ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId;
        }
#if !USE_UNICODE_WCHAR_CACHE
        PyMem_Free(Host);
#endif /* USE_UNICODE_WCHAR_CACHE */
        return Length;
    }
    default:
        PyErr_SetString(PyExc_ValueError, "illegal address_as_bytes argument");
        return -1;
    }
}

/*[clinic input]
_overlapped.Overlapped.ConnectEx

    client_handle as ConnectSocket: HANDLE
    address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
    /

Start overlapped connect.

client_handle should be unbound.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self,
                                      HANDLE ConnectSocket,
                                      PyObject *AddressObj)
/*[clinic end generated code: output=5aebbbdb4f022833 input=d6bbd2d84b156fc1]*/
{
    char AddressBuf[sizeof(struct sockaddr_in6)];
    SOCKADDR *Address = (SOCKADDR*)AddressBuf;
    int Length;
    BOOL ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

    Length = sizeof(AddressBuf);
    Length = parse_address(AddressObj, Address, Length);
    if (Length < 0)
        return NULL;

    self->type = TYPE_CONNECT;
    self->handle = ConnectSocket;

    Py_BEGIN_ALLOW_THREADS
    ret = Py_ConnectEx((SOCKET)ConnectSocket, Address, Length,
                       NULL, 0, NULL, &self->overlapped);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}

/*[clinic input]
_overlapped.Overlapped.DisconnectEx

    handle as Socket: HANDLE
    flags: DWORD
    /

[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self,
                                         HANDLE Socket, DWORD flags)
/*[clinic end generated code: output=8d64ddb8c93c2126 input=680845cdcdf820eb]*/
{
    BOOL ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

    self->type = TYPE_DISCONNECT;
    self->handle = Socket;

    Py_BEGIN_ALLOW_THREADS
    ret = Py_DisconnectEx((SOCKET)Socket, &self->overlapped, flags, 0);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}

/*[clinic input]
_overlapped.Overlapped.TransmitFile

    socket as Socket: HANDLE
    file as File: HANDLE
    offset: DWORD
    offset_high: DWORD
    count_to_write: DWORD
    count_per_send: DWORD
    flags: DWORD
    /

Transmit file data over a connected socket.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self,
                                         HANDLE Socket, HANDLE File,
                                         DWORD offset, DWORD offset_high,
                                         DWORD count_to_write,
                                         DWORD count_per_send, DWORD flags)
/*[clinic end generated code: output=03f3ca5512e678fd input=7e6f97b391f60e8c]*/
{
    BOOL ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

    self->type = TYPE_TRANSMIT_FILE;
    self->handle = Socket;
    self->overlapped.Offset = offset;
    self->overlapped.OffsetHigh = offset_high;

    Py_BEGIN_ALLOW_THREADS
    ret = Py_TransmitFile((SOCKET)Socket, File, count_to_write,
                          count_per_send, &self->overlapped, NULL, flags);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}

/*[clinic input]
_overlapped.Overlapped.ConnectNamedPipe

    handle as Pipe: HANDLE
    /

Start overlapped wait for a client to connect.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self,
                                             HANDLE Pipe)
/*[clinic end generated code: output=3e69adfe55818abe input=8b0d4cef8a72f7bc]*/
{
    BOOL ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

    self->type = TYPE_CONNECT_NAMED_PIPE;
    self->handle = Pipe;

    Py_BEGIN_ALLOW_THREADS
    ret = ConnectNamedPipe(Pipe, &self->overlapped);
    Py_END_ALLOW_THREADS

    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
    switch (err) {
        case ERROR_PIPE_CONNECTED:
            mark_as_completed(&self->overlapped);
            Py_RETURN_TRUE;
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_FALSE;
        default:
            Overlapped_clear(self);
            return SetFromWindowsErr(err);
    }
}

/*[clinic input]
_overlapped.Overlapped.ConnectPipe

    addr as Address: Py_UNICODE
    /

Connect to the pipe for asynchronous I/O (overlapped).
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self,
                                        const Py_UNICODE *Address)
/*[clinic end generated code: output=3cc9661667d459d4 input=167c06a274efcefc]*/
{
    HANDLE PipeHandle;

    Py_BEGIN_ALLOW_THREADS
    PipeHandle = CreateFileW(Address,
                             GENERIC_READ | GENERIC_WRITE,
                             0, NULL, OPEN_EXISTING,
                             FILE_FLAG_OVERLAPPED, NULL);
    Py_END_ALLOW_THREADS

    if (PipeHandle == INVALID_HANDLE_VALUE)
        return SetFromWindowsErr(0);
    return Py_BuildValue(F_HANDLE, PipeHandle);
}

static PyObject*
Overlapped_getaddress(OverlappedObject *self)
{
    return PyLong_FromVoidPtr(&self->overlapped);
}

static PyObject*
Overlapped_getpending(OverlappedObject *self)
{
    return PyBool_FromLong(!HasOverlappedIoCompleted(&self->overlapped) &&
                           self->type != TYPE_NOT_STARTED);
}

static int
Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
{
    switch (self->type) {
    case TYPE_READ:
    case TYPE_ACCEPT:
        Py_VISIT(self->allocated_buffer);
        break;
    case TYPE_WRITE:
    case TYPE_WRITE_TO:
    case TYPE_READINTO:
        if (self->user_buffer.obj) {
            Py_VISIT(&self->user_buffer.obj);
        }
        break;
    case TYPE_READ_FROM:
        Py_VISIT(self->read_from.result);
        Py_VISIT(self->read_from.allocated_buffer);
        break;
    case TYPE_READ_FROM_INTO:
        Py_VISIT(self->read_from_into.result);
        if (self->read_from_into.user_buffer.obj) {
            Py_VISIT(&self->read_from_into.user_buffer.obj);
        }
        break;
    }
    return 0;
}

// UDP functions

/*
 * Note: WSAConnect does not support Overlapped I/O so this function should
 * _only_ be used for connectionless sockets (UDP).
 */

/*[clinic input]
_overlapped.WSAConnect

    client_handle as ConnectSocket: HANDLE
    address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
    /

Bind a remote address to a connectionless (UDP) socket.
[clinic start generated code]*/

static PyObject *
_overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket,
                            PyObject *AddressObj)
/*[clinic end generated code: output=ea0b4391e94dad63 input=7cf65313d49c015a]*/
{
    char AddressBuf[sizeof(struct sockaddr_in6)];
    SOCKADDR *Address = (SOCKADDR*)AddressBuf;
    int Length;
    int err;

    Length = sizeof(AddressBuf);
    Length = parse_address(AddressObj, Address, Length);
    if (Length < 0) {
        return NULL;
    }

    Py_BEGIN_ALLOW_THREADS
    // WSAConnect does not support overlapped I/O so this call will
    // successfully complete immediately.
    err = WSAConnect((SOCKET)ConnectSocket, Address, Length,
                        NULL, NULL, NULL, NULL);
    Py_END_ALLOW_THREADS

    if (err == 0) {
        Py_RETURN_NONE;
    }
    else {
        return SetFromWindowsErr(WSAGetLastError());
    }
}

/*[clinic input]
_overlapped.Overlapped.WSASendTo

    handle: HANDLE
    buf as bufobj: Py_buffer
    flags: DWORD
    address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
    /

Start overlapped sendto over a connectionless (UDP) socket.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
                                      Py_buffer *bufobj, DWORD flags,
                                      PyObject *AddressObj)
/*[clinic end generated code: output=3cdedc4cfaeb70cd input=31f44cd4ab92fc33]*/
{
    char AddressBuf[sizeof(struct sockaddr_in6)];
    SOCKADDR *Address = (SOCKADDR*)AddressBuf;
    int AddressLength;
    DWORD written;
    WSABUF wsabuf;
    int ret;
    DWORD err;

    // Parse the "to" address
    AddressLength = sizeof(AddressBuf);
    AddressLength = parse_address(AddressObj, Address, AddressLength);
    if (AddressLength < 0) {
        return NULL;
    }

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T > SIZEOF_LONG
    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
        PyErr_SetString(PyExc_ValueError, "buffer too large");
        return NULL;
    }
#endif
    steal_buffer(&self->user_buffer, bufobj);

    self->type = TYPE_WRITE_TO;
    self->handle = handle;
    wsabuf.len = (DWORD)self->user_buffer.len;
    wsabuf.buf = self->user_buffer.buf;

    Py_BEGIN_ALLOW_THREADS
    ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags,
                    Address, AddressLength, &self->overlapped, NULL);
    Py_END_ALLOW_THREADS

    self->error = err = (ret == SOCKET_ERROR ? WSAGetLastError() :
                                               ERROR_SUCCESS);

    switch(err) {
        case ERROR_SUCCESS:
        case ERROR_IO_PENDING:
            Py_RETURN_NONE;
        default:
            self->type = TYPE_NOT_STARTED;
            return SetFromWindowsErr(err);
    }
}



PyDoc_STRVAR(
    Overlapped_WSARecvFrom_doc,
    "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n"
    "Start overlapped receive");

/*[clinic input]
_overlapped.Overlapped.WSARecvFrom

    handle: HANDLE
    size: DWORD
    flags: DWORD = 0
    /

Start overlapped receive.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self,
                                        HANDLE handle, DWORD size,
                                        DWORD flags)
/*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/
{
    PyObject *buf;
    DWORD nread;
    WSABUF wsabuf;
    int ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T <= SIZEOF_LONG
    size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
#endif
    buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
    if (buf == NULL) {
        return NULL;
    }

    wsabuf.buf = PyBytes_AS_STRING(buf);
    wsabuf.len = size;

    self->type = TYPE_READ_FROM;
    self->handle = handle;
    self->read_from.allocated_buffer = buf;
    memset(&self->read_from.address, 0, sizeof(self->read_from.address));
    self->read_from.address_length = sizeof(self->read_from.address);

    Py_BEGIN_ALLOW_THREADS
    ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
                      (SOCKADDR*)&self->read_from.address,
                      &self->read_from.address_length,
                      &self->overlapped, NULL);
    Py_END_ALLOW_THREADS

    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
    switch (err) {
    case ERROR_BROKEN_PIPE:
        mark_as_completed(&self->overlapped);
        return SetFromWindowsErr(err);
    case ERROR_SUCCESS:
    case ERROR_MORE_DATA:
    case ERROR_IO_PENDING:
        Py_RETURN_NONE;
    default:
        self->type = TYPE_NOT_STARTED;
        return SetFromWindowsErr(err);
    }
}


/*[clinic input]
_overlapped.Overlapped.WSARecvFromInto

    handle: HANDLE
    buf as bufobj: Py_buffer
    size: DWORD
    flags: DWORD = 0
    /

Start overlapped receive.
[clinic start generated code]*/

static PyObject *
_overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self,
                                            HANDLE handle, Py_buffer *bufobj,
                                            DWORD size, DWORD flags)
/*[clinic end generated code: output=30c7ea171a691757 input=4be4b08d03531e76]*/
{
    DWORD nread;
    WSABUF wsabuf;
    int ret;
    DWORD err;

    if (self->type != TYPE_NONE) {
        PyErr_SetString(PyExc_ValueError, "operation already attempted");
        return NULL;
    }

#if SIZEOF_SIZE_T > SIZEOF_LONG
    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
        PyErr_SetString(PyExc_ValueError, "buffer too large");
        return NULL;
    }
#endif

    wsabuf.buf = bufobj->buf;
    wsabuf.len = size;

    self->type = TYPE_READ_FROM_INTO;
    self->handle = handle;
    steal_buffer(&self->read_from_into.user_buffer, bufobj);
    memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address));
    self->read_from_into.address_length = sizeof(self->read_from_into.address);

    Py_BEGIN_ALLOW_THREADS
    ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
                      (SOCKADDR*)&self->read_from_into.address,
                      &self->read_from_into.address_length,
                      &self->overlapped, NULL);
    Py_END_ALLOW_THREADS

    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
    switch (err) {
    case ERROR_BROKEN_PIPE:
        mark_as_completed(&self->overlapped);
        return SetFromWindowsErr(err);
    case ERROR_SUCCESS:
    case ERROR_MORE_DATA:
    case ERROR_IO_PENDING:
        Py_RETURN_NONE;
    default:
        self->type = TYPE_NOT_STARTED;
        return SetFromWindowsErr(err);
    }
}


#include "clinic/overlapped.c.h"

static PyMethodDef Overlapped_methods[] = {
    _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF
    _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF
    _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF
    _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF
    _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF
    _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF
    _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
    _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF
    _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF
    _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF
    _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF
    _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF
    _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF
    _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF
    _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF
    _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
    _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF
    {NULL}
};

static PyMemberDef Overlapped_members[] = {
    {"error", T_ULONG,
     offsetof(OverlappedObject, error),
     READONLY, "Error from last operation"},
    {"event", T_HANDLE,
     offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
     READONLY, "Overlapped event handle"},
    {NULL}
};

static PyGetSetDef Overlapped_getsets[] = {
    {"address", (getter)Overlapped_getaddress, NULL,
     "Address of overlapped structure"},
    {"pending", (getter)Overlapped_getpending, NULL,
     "Whether the operation is pending"},
    {NULL},
};

static PyType_Slot overlapped_type_slots[] = {
    {Py_tp_dealloc, Overlapped_dealloc},
    {Py_tp_doc, (char *)_overlapped_Overlapped__doc__},
    {Py_tp_traverse, Overlapped_traverse},
    {Py_tp_methods, Overlapped_methods},
    {Py_tp_members, Overlapped_members},
    {Py_tp_getset, Overlapped_getsets},
    {Py_tp_new, _overlapped_Overlapped},
    {0,0}
};

static PyType_Spec overlapped_type_spec = {
    .name = "_overlapped.Overlapped",
    .basicsize = sizeof(OverlappedObject),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
    .slots = overlapped_type_slots
};

static PyMethodDef overlapped_functions[] = {
    _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF
    _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF
    _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF
    _OVERLAPPED_FORMATMESSAGE_METHODDEF
    _OVERLAPPED_BINDLOCAL_METHODDEF
    _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF
    _OVERLAPPED_UNREGISTERWAIT_METHODDEF
    _OVERLAPPED_UNREGISTERWAITEX_METHODDEF
    _OVERLAPPED_CREATEEVENT_METHODDEF
    _OVERLAPPED_SETEVENT_METHODDEF
    _OVERLAPPED_RESETEVENT_METHODDEF
    _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF
    _OVERLAPPED_WSACONNECT_METHODDEF
    {NULL}
};

static int
overlapped_traverse(PyObject *module, visitproc visit, void *arg)
{
    OverlappedState *state = overlapped_get_state(module);
    Py_VISIT(state->overlapped_type);
    return 0;
}

static int
overlapped_clear(PyObject *module)
{
    OverlappedState *state = overlapped_get_state(module);
    Py_CLEAR(state->overlapped_type);
    return 0;
}

static void
overlapped_free(void *module)
{
    overlapped_clear((PyObject *)module);
}

#define WINAPI_CONSTANT(fmt, con) \
    do { \
        PyObject *value = Py_BuildValue(fmt, con); \
        if (value == NULL) { \
            return -1; \
        } \
        if (PyModule_AddObject(module, #con, value) < 0 ) { \
            Py_DECREF(value); \
            return -1; \
        } \
    } while (0)

static int
overlapped_exec(PyObject *module)
{
    /* Ensure WSAStartup() called before initializing function pointers */
    PyObject *socket_module = PyImport_ImportModule("_socket");
    if (!socket_module) {
        return -1;
    }

    Py_DECREF(socket_module);

    if (initialize_function_pointers() < 0) {
        return -1;
    }

    OverlappedState *st = overlapped_get_state(module);
    st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(
        module, &overlapped_type_spec, NULL);
    if (st->overlapped_type == NULL) {
        return -1;
    }

    if (PyModule_AddType(module, st->overlapped_type) < 0) {
        return -1;
    }

    WINAPI_CONSTANT(F_DWORD,  ERROR_IO_PENDING);
    WINAPI_CONSTANT(F_DWORD,  ERROR_NETNAME_DELETED);
    WINAPI_CONSTANT(F_DWORD,  ERROR_OPERATION_ABORTED);
    WINAPI_CONSTANT(F_DWORD,  ERROR_SEM_TIMEOUT);
    WINAPI_CONSTANT(F_DWORD,  ERROR_PIPE_BUSY);
    WINAPI_CONSTANT(F_DWORD,  ERROR_PORT_UNREACHABLE);
    WINAPI_CONSTANT(F_DWORD,  INFINITE);
    WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE);
    WINAPI_CONSTANT(F_HANDLE, NULL);
    WINAPI_CONSTANT(F_DWORD,  SO_UPDATE_ACCEPT_CONTEXT);
    WINAPI_CONSTANT(F_DWORD,  SO_UPDATE_CONNECT_CONTEXT);
    WINAPI_CONSTANT(F_DWORD,  TF_REUSE_SOCKET);

    return 0;
}

static PyModuleDef_Slot overlapped_slots[] = {
    {Py_mod_exec, overlapped_exec},
    {0, NULL}
};

static struct PyModuleDef overlapped_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_overlapped",
    .m_size = sizeof(OverlappedState),
    .m_methods = overlapped_functions,
    .m_slots = overlapped_slots,
    .m_traverse = overlapped_traverse,
    .m_clear = overlapped_clear,
    .m_free = overlapped_free
};

PyMODINIT_FUNC
PyInit__overlapped(void)
{
    return PyModuleDef_Init(&overlapped_module);
}
