/*
 * 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

/* Compatibility with Python 3.3 */
#if PY_VERSION_HEX < 0x03040000
#    define PyMem_RawMalloc PyMem_Malloc
#    define PyMem_RawFree PyMem_Free
#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};

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;
    };
} 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;
}


/*
 * 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;
static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = 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;
    HINSTANCE hKernel32;
    SOCKET s;
    DWORD dwBytes;

    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);

    /* On WinXP we will have Py_CancelIoEx == NULL */
    Py_BEGIN_ALLOW_THREADS
    hKernel32 = GetModuleHandle("KERNEL32");
    *(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx");
    Py_END_ALLOW_THREADS
    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))
    {
        PyMem_RawFree(pdata);
        return SetFromWindowsErr(0);
    }

    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 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_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)
    {
        if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped))
            wait = TRUE;

        Py_BEGIN_ALLOW_THREADS
        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
        if (Py_CancelIoEx)
            ret = Py_CancelIoEx(self->handle, &self->overlapped);
        else
            ret = CancelIo(self->handle);
        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;
            }
            /* 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;
        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: object
    /

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

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

    if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
        return NULL;

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

    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: object
    flags: DWORD
    /

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

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

    if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
        return NULL;

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

    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: object
    /

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

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

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

    if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
        return NULL;

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

    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: object
    flags: DWORD
    /

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

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

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

    if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
        return NULL;

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

    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);
    }
    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
    /

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=169f8075e9ae7fa4]*/
{
    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: object
    flags: DWORD
    address_as_bytes as AddressObj: object
    /

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

static PyObject *
_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
                                      PyObject *bufobj, DWORD flags,
                                      PyObject *AddressObj)
/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/
{
    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 (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) {
        return NULL;
    }

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

    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]*/
{
    DWORD nread;
    PyObject *buf;
    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.len = size;
    wsabuf.buf = PyBytes_AS_STRING(buf);

    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);
    }
}

#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_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,
    .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,  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);
}
