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

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

#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"

#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 Py_T_ULONG
#else
#  define F_POINTER "K"
#  define T_POINTER Py_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 pointer_converter(CConverter):
    format_unit = '"F_POINTER"'

    def parse_arg(self, argname, displayname, *, limited_capi):
        return self.format_code("""
            {paramname} = PyLong_AsVoidPtr({argname});
            if (!{paramname} && PyErr_Occurred()) {{{{
                goto exit;
            }}}}
            """,
            argname=argname)

class OVERLAPPED_converter(pointer_converter):
    type = 'OVERLAPPED *'

class HANDLE_converter(pointer_converter):
    type = 'HANDLE'

class ULONG_PTR_converter(pointer_converter):
    type = 'ULONG_PTR'

    def parse_arg(self, argname, displayname, *, limited_capi):
        return self.format_code("""
            {paramname} = (uintptr_t)PyLong_AsVoidPtr({argname});
            if (!{paramname} && PyErr_Occurred()) {{{{
                goto exit;
            }}}}
            """,
            argname=argname)

class DWORD_converter(unsigned_long_converter):
    type = 'DWORD'

class BOOL_converter(int_converter):
    type = 'BOOL'
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=436f4440630a304c]*/

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


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 wchar_t *Name)
/*[clinic end generated code: output=b17ddc5fd506972d 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;
        res = PyUnicode_FromWideChar(lpMsgBuf, n);
    } 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;

            return Py_NewRef(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
            PyTuple_SET_ITEM(self->read_from.result, 0,
                             Py_NewRef(self->read_from.allocated_buffer));
            // second item: address
            PyTuple_SET_ITEM(self->read_from.result, 1, addr);

            return Py_NewRef(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);

            return Py_NewRef(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;
    wchar_t *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;
        }
        Host = PyUnicode_AsWideCharString(Host_obj, NULL);
        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);
        }
        PyMem_Free(Host);
        return Length;
    }
    case 4: {
        if (!PyArg_ParseTuple(obj,
                "UHkk;ConnectEx(): illegal address_as_bytes argument",
                &Host_obj, &Port, &FlowInfo, &ScopeId))
        {
            return -1;
        }
        Host = PyUnicode_AsWideCharString(Host_obj, NULL);
        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;
        }
        PyMem_Free(Host);
        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 wchar_t *Address)
/*[clinic end generated code: output=67cbd8e4d3a57855 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", Py_T_ULONG,
     offsetof(OverlappedObject, error),
     Py_READONLY, "Error from last operation"},
    {"event", T_HANDLE,
     offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
     Py_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}
};

#define WINAPI_CONSTANT(fmt, con) \
    do { \
        if (PyModule_Add(module, #con, Py_BuildValue(fmt, con)) < 0 ) { \
            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;
    }

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

    int rc = PyModule_AddType(module, overlapped_type);
    Py_DECREF(overlapped_type);
    if (rc < 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},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef overlapped_module = {
    .m_base = PyModuleDef_HEAD_INIT,
    .m_name = "_overlapped",
    .m_methods = overlapped_functions,
    .m_slots = overlapped_slots,
};

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