17db96d56Sopenharmony_ci/*
27db96d56Sopenharmony_ci * Support for overlapped IO
37db96d56Sopenharmony_ci *
47db96d56Sopenharmony_ci * Some code borrowed from Modules/_winapi.c of CPython
57db96d56Sopenharmony_ci */
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci/* XXX check overflow and DWORD <-> Py_ssize_t conversions
87db96d56Sopenharmony_ci   Check itemsize */
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci#include "Python.h"
117db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ci#define WINDOWS_LEAN_AND_MEAN
147db96d56Sopenharmony_ci#include <winsock2.h>
157db96d56Sopenharmony_ci#include <ws2tcpip.h>
167db96d56Sopenharmony_ci#include <mswsock.h>
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci#if defined(MS_WIN32) && !defined(MS_WIN64)
197db96d56Sopenharmony_ci#  define F_POINTER "k"
207db96d56Sopenharmony_ci#  define T_POINTER T_ULONG
217db96d56Sopenharmony_ci#else
227db96d56Sopenharmony_ci#  define F_POINTER "K"
237db96d56Sopenharmony_ci#  define T_POINTER T_ULONGLONG
247db96d56Sopenharmony_ci#endif
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci#define F_HANDLE F_POINTER
277db96d56Sopenharmony_ci#define F_ULONG_PTR F_POINTER
287db96d56Sopenharmony_ci#define F_DWORD "k"
297db96d56Sopenharmony_ci#define F_BOOL "i"
307db96d56Sopenharmony_ci#define F_UINT "I"
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci#define T_HANDLE T_POINTER
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ci/*[python input]
357db96d56Sopenharmony_ciclass OVERLAPPED_converter(CConverter):
367db96d56Sopenharmony_ci    type = 'OVERLAPPED *'
377db96d56Sopenharmony_ci    format_unit = '"F_POINTER"'
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ciclass HANDLE_converter(CConverter):
407db96d56Sopenharmony_ci    type = 'HANDLE'
417db96d56Sopenharmony_ci    format_unit = '"F_HANDLE"'
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ciclass ULONG_PTR_converter(CConverter):
447db96d56Sopenharmony_ci    type = 'ULONG_PTR'
457db96d56Sopenharmony_ci    format_unit = '"F_ULONG_PTR"'
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ciclass DWORD_converter(CConverter):
487db96d56Sopenharmony_ci    type = 'DWORD'
497db96d56Sopenharmony_ci    format_unit = 'k'
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ciclass BOOL_converter(CConverter):
527db96d56Sopenharmony_ci    type = 'BOOL'
537db96d56Sopenharmony_ci    format_unit = 'i'
547db96d56Sopenharmony_ci[python start generated code]*/
557db96d56Sopenharmony_ci/*[python end generated code: output=da39a3ee5e6b4b0d input=83bb8c2c2514f2a8]*/
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci/*[clinic input]
587db96d56Sopenharmony_cimodule _overlapped
597db96d56Sopenharmony_ciclass _overlapped.Overlapped "OverlappedObject *" "&OverlappedType"
607db96d56Sopenharmony_ci[clinic start generated code]*/
617db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92e5a799db35b96c]*/
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_cienum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE,
657db96d56Sopenharmony_ci      TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE,
667db96d56Sopenharmony_ci      TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM,
677db96d56Sopenharmony_ci      TYPE_WRITE_TO, TYPE_READ_FROM_INTO};
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_citypedef struct {
707db96d56Sopenharmony_ci    PyObject_HEAD
717db96d56Sopenharmony_ci    OVERLAPPED overlapped;
727db96d56Sopenharmony_ci    /* For convenience, we store the file handle too */
737db96d56Sopenharmony_ci    HANDLE handle;
747db96d56Sopenharmony_ci    /* Error returned by last method call */
757db96d56Sopenharmony_ci    DWORD error;
767db96d56Sopenharmony_ci    /* Type of operation */
777db96d56Sopenharmony_ci    DWORD type;
787db96d56Sopenharmony_ci    union {
797db96d56Sopenharmony_ci        /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */
807db96d56Sopenharmony_ci        PyObject *allocated_buffer;
817db96d56Sopenharmony_ci        /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */
827db96d56Sopenharmony_ci        Py_buffer user_buffer;
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci        /* Data used for reading from a connectionless socket:
857db96d56Sopenharmony_ci           TYPE_READ_FROM */
867db96d56Sopenharmony_ci        struct {
877db96d56Sopenharmony_ci            // A (buffer, (host, port)) tuple
887db96d56Sopenharmony_ci            PyObject *result;
897db96d56Sopenharmony_ci            // The actual read buffer
907db96d56Sopenharmony_ci            PyObject *allocated_buffer;
917db96d56Sopenharmony_ci            struct sockaddr_in6 address;
927db96d56Sopenharmony_ci            int address_length;
937db96d56Sopenharmony_ci        } read_from;
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci        /* Data used for reading from a connectionless socket:
967db96d56Sopenharmony_ci           TYPE_READ_FROM_INTO */
977db96d56Sopenharmony_ci        struct {
987db96d56Sopenharmony_ci            // A (number of bytes read, (host, port)) tuple
997db96d56Sopenharmony_ci            PyObject* result;
1007db96d56Sopenharmony_ci            /* Buffer passed by the user */
1017db96d56Sopenharmony_ci            Py_buffer user_buffer;
1027db96d56Sopenharmony_ci            struct sockaddr_in6 address;
1037db96d56Sopenharmony_ci            int address_length;
1047db96d56Sopenharmony_ci        } read_from_into;
1057db96d56Sopenharmony_ci    };
1067db96d56Sopenharmony_ci} OverlappedObject;
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_citypedef struct {
1097db96d56Sopenharmony_ci    PyTypeObject *overlapped_type;
1107db96d56Sopenharmony_ci} OverlappedState;
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_cistatic inline OverlappedState*
1137db96d56Sopenharmony_cioverlapped_get_state(PyObject *module)
1147db96d56Sopenharmony_ci{
1157db96d56Sopenharmony_ci    void *state = PyModule_GetState(module);
1167db96d56Sopenharmony_ci    assert(state != NULL);
1177db96d56Sopenharmony_ci    return (OverlappedState *)state;
1187db96d56Sopenharmony_ci}
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_cistatic inline void
1227db96d56Sopenharmony_cisteal_buffer(Py_buffer * dst, Py_buffer * src)
1237db96d56Sopenharmony_ci{
1247db96d56Sopenharmony_ci    memcpy(dst, src, sizeof(Py_buffer));
1257db96d56Sopenharmony_ci    memset(src, 0, sizeof(Py_buffer));
1267db96d56Sopenharmony_ci}
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci/*
1297db96d56Sopenharmony_ci * Map Windows error codes to subclasses of OSError
1307db96d56Sopenharmony_ci */
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_cistatic PyObject *
1337db96d56Sopenharmony_ciSetFromWindowsErr(DWORD err)
1347db96d56Sopenharmony_ci{
1357db96d56Sopenharmony_ci    PyObject *exception_type;
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci    if (err == 0)
1387db96d56Sopenharmony_ci        err = GetLastError();
1397db96d56Sopenharmony_ci    switch (err) {
1407db96d56Sopenharmony_ci        case ERROR_CONNECTION_REFUSED:
1417db96d56Sopenharmony_ci            exception_type = PyExc_ConnectionRefusedError;
1427db96d56Sopenharmony_ci            break;
1437db96d56Sopenharmony_ci        case ERROR_CONNECTION_ABORTED:
1447db96d56Sopenharmony_ci            exception_type = PyExc_ConnectionAbortedError;
1457db96d56Sopenharmony_ci            break;
1467db96d56Sopenharmony_ci        default:
1477db96d56Sopenharmony_ci            exception_type = PyExc_OSError;
1487db96d56Sopenharmony_ci    }
1497db96d56Sopenharmony_ci    return PyErr_SetExcFromWindowsErr(exception_type, err);
1507db96d56Sopenharmony_ci}
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci/*
1537db96d56Sopenharmony_ci * Some functions should be loaded at runtime
1547db96d56Sopenharmony_ci */
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_cistatic LPFN_ACCEPTEX Py_AcceptEx = NULL;
1577db96d56Sopenharmony_cistatic LPFN_CONNECTEX Py_ConnectEx = NULL;
1587db96d56Sopenharmony_cistatic LPFN_DISCONNECTEX Py_DisconnectEx = NULL;
1597db96d56Sopenharmony_cistatic LPFN_TRANSMITFILE Py_TransmitFile = NULL;
1607db96d56Sopenharmony_ci
1617db96d56Sopenharmony_ci#define GET_WSA_POINTER(s, x)                                           \
1627db96d56Sopenharmony_ci    (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,    \
1637db96d56Sopenharmony_ci                              &Guid##x, sizeof(Guid##x), &Py_##x,       \
1647db96d56Sopenharmony_ci                              sizeof(Py_##x), &dwBytes, NULL, NULL))
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_cistatic int
1677db96d56Sopenharmony_ciinitialize_function_pointers(void)
1687db96d56Sopenharmony_ci{
1697db96d56Sopenharmony_ci    GUID GuidAcceptEx = WSAID_ACCEPTEX;
1707db96d56Sopenharmony_ci    GUID GuidConnectEx = WSAID_CONNECTEX;
1717db96d56Sopenharmony_ci    GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
1727db96d56Sopenharmony_ci    GUID GuidTransmitFile = WSAID_TRANSMITFILE;
1737db96d56Sopenharmony_ci    SOCKET s;
1747db96d56Sopenharmony_ci    DWORD dwBytes;
1757db96d56Sopenharmony_ci
1767db96d56Sopenharmony_ci    if (Py_AcceptEx != NULL &&
1777db96d56Sopenharmony_ci        Py_ConnectEx != NULL &&
1787db96d56Sopenharmony_ci        Py_DisconnectEx != NULL &&
1797db96d56Sopenharmony_ci        Py_TransmitFile != NULL)
1807db96d56Sopenharmony_ci    {
1817db96d56Sopenharmony_ci        // All function pointers are initialized already
1827db96d56Sopenharmony_ci        // by previous module import
1837db96d56Sopenharmony_ci        return 0;
1847db96d56Sopenharmony_ci    }
1857db96d56Sopenharmony_ci
1867db96d56Sopenharmony_ci    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1877db96d56Sopenharmony_ci    if (s == INVALID_SOCKET) {
1887db96d56Sopenharmony_ci        SetFromWindowsErr(WSAGetLastError());
1897db96d56Sopenharmony_ci        return -1;
1907db96d56Sopenharmony_ci    }
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ci    if (!GET_WSA_POINTER(s, AcceptEx) ||
1937db96d56Sopenharmony_ci        !GET_WSA_POINTER(s, ConnectEx) ||
1947db96d56Sopenharmony_ci        !GET_WSA_POINTER(s, DisconnectEx) ||
1957db96d56Sopenharmony_ci        !GET_WSA_POINTER(s, TransmitFile))
1967db96d56Sopenharmony_ci    {
1977db96d56Sopenharmony_ci        closesocket(s);
1987db96d56Sopenharmony_ci        SetFromWindowsErr(WSAGetLastError());
1997db96d56Sopenharmony_ci        return -1;
2007db96d56Sopenharmony_ci    }
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci    closesocket(s);
2037db96d56Sopenharmony_ci    return 0;
2047db96d56Sopenharmony_ci}
2057db96d56Sopenharmony_ci
2067db96d56Sopenharmony_ci/*
2077db96d56Sopenharmony_ci * Completion port stuff
2087db96d56Sopenharmony_ci */
2097db96d56Sopenharmony_ci
2107db96d56Sopenharmony_ci/*[clinic input]
2117db96d56Sopenharmony_ci_overlapped.CreateIoCompletionPort
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci    handle as FileHandle: HANDLE
2147db96d56Sopenharmony_ci    port as ExistingCompletionPort: HANDLE
2157db96d56Sopenharmony_ci    key as CompletionKey: ULONG_PTR
2167db96d56Sopenharmony_ci    concurrency as NumberOfConcurrentThreads: DWORD
2177db96d56Sopenharmony_ci    /
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ciCreate a completion port or register a handle with a port.
2207db96d56Sopenharmony_ci[clinic start generated code]*/
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_cistatic PyObject *
2237db96d56Sopenharmony_ci_overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle,
2247db96d56Sopenharmony_ci                                        HANDLE ExistingCompletionPort,
2257db96d56Sopenharmony_ci                                        ULONG_PTR CompletionKey,
2267db96d56Sopenharmony_ci                                        DWORD NumberOfConcurrentThreads)
2277db96d56Sopenharmony_ci/*[clinic end generated code: output=24ede2b0f05e5433 input=847bae4d0efe1976]*/
2287db96d56Sopenharmony_ci{
2297db96d56Sopenharmony_ci    HANDLE ret;
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
2327db96d56Sopenharmony_ci    ret = CreateIoCompletionPort(FileHandle, ExistingCompletionPort,
2337db96d56Sopenharmony_ci                                 CompletionKey, NumberOfConcurrentThreads);
2347db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
2357db96d56Sopenharmony_ci
2367db96d56Sopenharmony_ci    if (ret == NULL)
2377db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
2387db96d56Sopenharmony_ci    return Py_BuildValue(F_HANDLE, ret);
2397db96d56Sopenharmony_ci}
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci/*[clinic input]
2427db96d56Sopenharmony_ci_overlapped.GetQueuedCompletionStatus
2437db96d56Sopenharmony_ci
2447db96d56Sopenharmony_ci    port as CompletionPort: HANDLE
2457db96d56Sopenharmony_ci    msecs as Milliseconds: DWORD
2467db96d56Sopenharmony_ci    /
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ciGet a message from completion port.
2497db96d56Sopenharmony_ci
2507db96d56Sopenharmony_ciWait for up to msecs milliseconds.
2517db96d56Sopenharmony_ci[clinic start generated code]*/
2527db96d56Sopenharmony_ci
2537db96d56Sopenharmony_cistatic PyObject *
2547db96d56Sopenharmony_ci_overlapped_GetQueuedCompletionStatus_impl(PyObject *module,
2557db96d56Sopenharmony_ci                                           HANDLE CompletionPort,
2567db96d56Sopenharmony_ci                                           DWORD Milliseconds)
2577db96d56Sopenharmony_ci/*[clinic end generated code: output=68314171628dddb7 input=94a042d14c4f6410]*/
2587db96d56Sopenharmony_ci{
2597db96d56Sopenharmony_ci    DWORD NumberOfBytes = 0;
2607db96d56Sopenharmony_ci    ULONG_PTR CompletionKey = 0;
2617db96d56Sopenharmony_ci    OVERLAPPED *Overlapped = NULL;
2627db96d56Sopenharmony_ci    DWORD err;
2637db96d56Sopenharmony_ci    BOOL ret;
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
2667db96d56Sopenharmony_ci    ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes,
2677db96d56Sopenharmony_ci                                    &CompletionKey, &Overlapped, Milliseconds);
2687db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    err = ret ? ERROR_SUCCESS : GetLastError();
2717db96d56Sopenharmony_ci    if (Overlapped == NULL) {
2727db96d56Sopenharmony_ci        if (err == WAIT_TIMEOUT)
2737db96d56Sopenharmony_ci            Py_RETURN_NONE;
2747db96d56Sopenharmony_ci        else
2757db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
2767db96d56Sopenharmony_ci    }
2777db96d56Sopenharmony_ci    return Py_BuildValue(F_DWORD F_DWORD F_ULONG_PTR F_POINTER,
2787db96d56Sopenharmony_ci                         err, NumberOfBytes, CompletionKey, Overlapped);
2797db96d56Sopenharmony_ci}
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci/*[clinic input]
2827db96d56Sopenharmony_ci_overlapped.PostQueuedCompletionStatus
2837db96d56Sopenharmony_ci
2847db96d56Sopenharmony_ci    port as CompletionPort: HANDLE
2857db96d56Sopenharmony_ci    bytes as NumberOfBytes: DWORD
2867db96d56Sopenharmony_ci    key as CompletionKey: ULONG_PTR
2877db96d56Sopenharmony_ci    address as Overlapped: OVERLAPPED
2887db96d56Sopenharmony_ci    /
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ciPost a message to completion port.
2917db96d56Sopenharmony_ci[clinic start generated code]*/
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_cistatic PyObject *
2947db96d56Sopenharmony_ci_overlapped_PostQueuedCompletionStatus_impl(PyObject *module,
2957db96d56Sopenharmony_ci                                            HANDLE CompletionPort,
2967db96d56Sopenharmony_ci                                            DWORD NumberOfBytes,
2977db96d56Sopenharmony_ci                                            ULONG_PTR CompletionKey,
2987db96d56Sopenharmony_ci                                            OVERLAPPED *Overlapped)
2997db96d56Sopenharmony_ci/*[clinic end generated code: output=93e73f2933a43e9e input=e936202d87937aca]*/
3007db96d56Sopenharmony_ci{
3017db96d56Sopenharmony_ci    BOOL ret;
3027db96d56Sopenharmony_ci
3037db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
3047db96d56Sopenharmony_ci    ret = PostQueuedCompletionStatus(CompletionPort, NumberOfBytes,
3057db96d56Sopenharmony_ci                                     CompletionKey, Overlapped);
3067db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
3077db96d56Sopenharmony_ci
3087db96d56Sopenharmony_ci    if (!ret)
3097db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
3107db96d56Sopenharmony_ci    Py_RETURN_NONE;
3117db96d56Sopenharmony_ci}
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci/*
3147db96d56Sopenharmony_ci * Wait for a handle
3157db96d56Sopenharmony_ci */
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_cistruct PostCallbackData {
3187db96d56Sopenharmony_ci    HANDLE CompletionPort;
3197db96d56Sopenharmony_ci    LPOVERLAPPED Overlapped;
3207db96d56Sopenharmony_ci};
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_cistatic VOID CALLBACK
3237db96d56Sopenharmony_ciPostToQueueCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
3247db96d56Sopenharmony_ci{
3257db96d56Sopenharmony_ci    struct PostCallbackData *p = (struct PostCallbackData*) lpParameter;
3267db96d56Sopenharmony_ci
3277db96d56Sopenharmony_ci    PostQueuedCompletionStatus(p->CompletionPort, TimerOrWaitFired,
3287db96d56Sopenharmony_ci                               0, p->Overlapped);
3297db96d56Sopenharmony_ci    /* ignore possible error! */
3307db96d56Sopenharmony_ci    PyMem_RawFree(p);
3317db96d56Sopenharmony_ci}
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci/*[clinic input]
3347db96d56Sopenharmony_ci_overlapped.RegisterWaitWithQueue
3357db96d56Sopenharmony_ci
3367db96d56Sopenharmony_ci    Object: HANDLE
3377db96d56Sopenharmony_ci    CompletionPort: HANDLE
3387db96d56Sopenharmony_ci    Overlapped: OVERLAPPED
3397db96d56Sopenharmony_ci    Timeout as Milliseconds: DWORD
3407db96d56Sopenharmony_ci    /
3417db96d56Sopenharmony_ci
3427db96d56Sopenharmony_ciRegister wait for Object; when complete CompletionPort is notified.
3437db96d56Sopenharmony_ci[clinic start generated code]*/
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_cistatic PyObject *
3467db96d56Sopenharmony_ci_overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object,
3477db96d56Sopenharmony_ci                                       HANDLE CompletionPort,
3487db96d56Sopenharmony_ci                                       OVERLAPPED *Overlapped,
3497db96d56Sopenharmony_ci                                       DWORD Milliseconds)
3507db96d56Sopenharmony_ci/*[clinic end generated code: output=c2ace732e447fe45 input=2dd4efee44abe8ee]*/
3517db96d56Sopenharmony_ci{
3527db96d56Sopenharmony_ci    HANDLE NewWaitObject;
3537db96d56Sopenharmony_ci    struct PostCallbackData data = {CompletionPort, Overlapped}, *pdata;
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ci    /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since
3567db96d56Sopenharmony_ci       PostToQueueCallback() will call PyMem_Free() from a new C thread
3577db96d56Sopenharmony_ci       which doesn't hold the GIL. */
3587db96d56Sopenharmony_ci    pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData));
3597db96d56Sopenharmony_ci    if (pdata == NULL)
3607db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
3617db96d56Sopenharmony_ci
3627db96d56Sopenharmony_ci    *pdata = data;
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci    if (!RegisterWaitForSingleObject(
3657db96d56Sopenharmony_ci            &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds,
3667db96d56Sopenharmony_ci            WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE))
3677db96d56Sopenharmony_ci    {
3687db96d56Sopenharmony_ci        PyMem_RawFree(pdata);
3697db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
3707db96d56Sopenharmony_ci    }
3717db96d56Sopenharmony_ci
3727db96d56Sopenharmony_ci    return Py_BuildValue(F_HANDLE, NewWaitObject);
3737db96d56Sopenharmony_ci}
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_ci/*[clinic input]
3767db96d56Sopenharmony_ci_overlapped.UnregisterWait
3777db96d56Sopenharmony_ci
3787db96d56Sopenharmony_ci    WaitHandle: HANDLE
3797db96d56Sopenharmony_ci    /
3807db96d56Sopenharmony_ci
3817db96d56Sopenharmony_ciUnregister wait handle.
3827db96d56Sopenharmony_ci[clinic start generated code]*/
3837db96d56Sopenharmony_ci
3847db96d56Sopenharmony_cistatic PyObject *
3857db96d56Sopenharmony_ci_overlapped_UnregisterWait_impl(PyObject *module, HANDLE WaitHandle)
3867db96d56Sopenharmony_ci/*[clinic end generated code: output=ec90cd955a9a617d input=a56709544cb2df0f]*/
3877db96d56Sopenharmony_ci{
3887db96d56Sopenharmony_ci    BOOL ret;
3897db96d56Sopenharmony_ci
3907db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
3917db96d56Sopenharmony_ci    ret = UnregisterWait(WaitHandle);
3927db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_ci    if (!ret)
3957db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
3967db96d56Sopenharmony_ci    Py_RETURN_NONE;
3977db96d56Sopenharmony_ci}
3987db96d56Sopenharmony_ci
3997db96d56Sopenharmony_ci/*[clinic input]
4007db96d56Sopenharmony_ci_overlapped.UnregisterWaitEx
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_ci    WaitHandle: HANDLE
4037db96d56Sopenharmony_ci    Event: HANDLE
4047db96d56Sopenharmony_ci    /
4057db96d56Sopenharmony_ci
4067db96d56Sopenharmony_ciUnregister wait handle.
4077db96d56Sopenharmony_ci[clinic start generated code]*/
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_cistatic PyObject *
4107db96d56Sopenharmony_ci_overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle,
4117db96d56Sopenharmony_ci                                  HANDLE Event)
4127db96d56Sopenharmony_ci/*[clinic end generated code: output=2e3d84c1d5f65b92 input=953cddc1de50fab9]*/
4137db96d56Sopenharmony_ci{
4147db96d56Sopenharmony_ci    BOOL ret;
4157db96d56Sopenharmony_ci
4167db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
4177db96d56Sopenharmony_ci    ret = UnregisterWaitEx(WaitHandle, Event);
4187db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
4197db96d56Sopenharmony_ci
4207db96d56Sopenharmony_ci    if (!ret)
4217db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
4227db96d56Sopenharmony_ci    Py_RETURN_NONE;
4237db96d56Sopenharmony_ci}
4247db96d56Sopenharmony_ci
4257db96d56Sopenharmony_ci/*
4267db96d56Sopenharmony_ci * Event functions -- currently only used by tests
4277db96d56Sopenharmony_ci */
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci/*[clinic input]
4307db96d56Sopenharmony_ci_overlapped.CreateEvent
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_ci    EventAttributes: object
4337db96d56Sopenharmony_ci    ManualReset: BOOL
4347db96d56Sopenharmony_ci    InitialState: BOOL
4357db96d56Sopenharmony_ci    Name: Py_UNICODE(accept={str, NoneType})
4367db96d56Sopenharmony_ci    /
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_ciCreate an event.
4397db96d56Sopenharmony_ci
4407db96d56Sopenharmony_ciEventAttributes must be None.
4417db96d56Sopenharmony_ci[clinic start generated code]*/
4427db96d56Sopenharmony_ci
4437db96d56Sopenharmony_cistatic PyObject *
4447db96d56Sopenharmony_ci_overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes,
4457db96d56Sopenharmony_ci                             BOOL ManualReset, BOOL InitialState,
4467db96d56Sopenharmony_ci                             const Py_UNICODE *Name)
4477db96d56Sopenharmony_ci/*[clinic end generated code: output=8e04f0916c17b13d input=dbc36ae14375ba24]*/
4487db96d56Sopenharmony_ci{
4497db96d56Sopenharmony_ci    HANDLE Event;
4507db96d56Sopenharmony_ci
4517db96d56Sopenharmony_ci    if (EventAttributes != Py_None) {
4527db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "EventAttributes must be None");
4537db96d56Sopenharmony_ci        return NULL;
4547db96d56Sopenharmony_ci    }
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
4577db96d56Sopenharmony_ci    Event = CreateEventW(NULL, ManualReset, InitialState, Name);
4587db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
4597db96d56Sopenharmony_ci
4607db96d56Sopenharmony_ci    if (Event == NULL)
4617db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
4627db96d56Sopenharmony_ci    return Py_BuildValue(F_HANDLE, Event);
4637db96d56Sopenharmony_ci}
4647db96d56Sopenharmony_ci
4657db96d56Sopenharmony_ci/*[clinic input]
4667db96d56Sopenharmony_ci_overlapped.SetEvent
4677db96d56Sopenharmony_ci
4687db96d56Sopenharmony_ci    Handle: HANDLE
4697db96d56Sopenharmony_ci    /
4707db96d56Sopenharmony_ci
4717db96d56Sopenharmony_ciSet event.
4727db96d56Sopenharmony_ci[clinic start generated code]*/
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_cistatic PyObject *
4757db96d56Sopenharmony_ci_overlapped_SetEvent_impl(PyObject *module, HANDLE Handle)
4767db96d56Sopenharmony_ci/*[clinic end generated code: output=5b8d974216b0e569 input=d8b0d26eb7391e80]*/
4777db96d56Sopenharmony_ci{
4787db96d56Sopenharmony_ci    BOOL ret;
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
4817db96d56Sopenharmony_ci    ret = SetEvent(Handle);
4827db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
4837db96d56Sopenharmony_ci
4847db96d56Sopenharmony_ci    if (!ret)
4857db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
4867db96d56Sopenharmony_ci    Py_RETURN_NONE;
4877db96d56Sopenharmony_ci}
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci/*[clinic input]
4907db96d56Sopenharmony_ci_overlapped.ResetEvent
4917db96d56Sopenharmony_ci
4927db96d56Sopenharmony_ci    Handle: HANDLE
4937db96d56Sopenharmony_ci    /
4947db96d56Sopenharmony_ci
4957db96d56Sopenharmony_ciReset event.
4967db96d56Sopenharmony_ci[clinic start generated code]*/
4977db96d56Sopenharmony_ci
4987db96d56Sopenharmony_cistatic PyObject *
4997db96d56Sopenharmony_ci_overlapped_ResetEvent_impl(PyObject *module, HANDLE Handle)
5007db96d56Sopenharmony_ci/*[clinic end generated code: output=066537a8405cddb2 input=d4e089c9ba84ff2f]*/
5017db96d56Sopenharmony_ci{
5027db96d56Sopenharmony_ci    BOOL ret;
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
5057db96d56Sopenharmony_ci    ret = ResetEvent(Handle);
5067db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci    if (!ret)
5097db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
5107db96d56Sopenharmony_ci    Py_RETURN_NONE;
5117db96d56Sopenharmony_ci}
5127db96d56Sopenharmony_ci
5137db96d56Sopenharmony_ci/*
5147db96d56Sopenharmony_ci * Bind socket handle to local port without doing slow getaddrinfo()
5157db96d56Sopenharmony_ci */
5167db96d56Sopenharmony_ci
5177db96d56Sopenharmony_ci/*[clinic input]
5187db96d56Sopenharmony_ci_overlapped.BindLocal
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_ci    handle as Socket: HANDLE
5217db96d56Sopenharmony_ci    family as Family: int
5227db96d56Sopenharmony_ci    /
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ciBind a socket handle to an arbitrary local port.
5257db96d56Sopenharmony_ci
5267db96d56Sopenharmony_cifamily should be AF_INET or AF_INET6.
5277db96d56Sopenharmony_ci[clinic start generated code]*/
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_cistatic PyObject *
5307db96d56Sopenharmony_ci_overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family)
5317db96d56Sopenharmony_ci/*[clinic end generated code: output=edb93862697aed9c input=a0e7b5c2f541170c]*/
5327db96d56Sopenharmony_ci{
5337db96d56Sopenharmony_ci    BOOL ret;
5347db96d56Sopenharmony_ci
5357db96d56Sopenharmony_ci    if (Family == AF_INET) {
5367db96d56Sopenharmony_ci        struct sockaddr_in addr;
5377db96d56Sopenharmony_ci        memset(&addr, 0, sizeof(addr));
5387db96d56Sopenharmony_ci        addr.sin_family = AF_INET;
5397db96d56Sopenharmony_ci        addr.sin_port = 0;
5407db96d56Sopenharmony_ci        addr.sin_addr.S_un.S_addr = INADDR_ANY;
5417db96d56Sopenharmony_ci        ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr))
5427db96d56Sopenharmony_ci                != SOCKET_ERROR;
5437db96d56Sopenharmony_ci    } else if (Family == AF_INET6) {
5447db96d56Sopenharmony_ci        struct sockaddr_in6 addr;
5457db96d56Sopenharmony_ci        memset(&addr, 0, sizeof(addr));
5467db96d56Sopenharmony_ci        addr.sin6_family = AF_INET6;
5477db96d56Sopenharmony_ci        addr.sin6_port = 0;
5487db96d56Sopenharmony_ci        addr.sin6_addr = in6addr_any;
5497db96d56Sopenharmony_ci        ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr))
5507db96d56Sopenharmony_ci                != SOCKET_ERROR;
5517db96d56Sopenharmony_ci    } else {
5527db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4");
5537db96d56Sopenharmony_ci        return NULL;
5547db96d56Sopenharmony_ci    }
5557db96d56Sopenharmony_ci
5567db96d56Sopenharmony_ci    if (!ret)
5577db96d56Sopenharmony_ci        return SetFromWindowsErr(WSAGetLastError());
5587db96d56Sopenharmony_ci    Py_RETURN_NONE;
5597db96d56Sopenharmony_ci}
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci/*
5627db96d56Sopenharmony_ci * Windows equivalent of os.strerror() -- compare _ctypes/callproc.c
5637db96d56Sopenharmony_ci */
5647db96d56Sopenharmony_ci
5657db96d56Sopenharmony_ci/*[clinic input]
5667db96d56Sopenharmony_ci_overlapped.FormatMessage
5677db96d56Sopenharmony_ci
5687db96d56Sopenharmony_ci    error_code as code: DWORD
5697db96d56Sopenharmony_ci    /
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ciReturn error message for an error code.
5727db96d56Sopenharmony_ci[clinic start generated code]*/
5737db96d56Sopenharmony_ci
5747db96d56Sopenharmony_cistatic PyObject *
5757db96d56Sopenharmony_ci_overlapped_FormatMessage_impl(PyObject *module, DWORD code)
5767db96d56Sopenharmony_ci/*[clinic end generated code: output=02c964ff22407c6b input=644bb5b80326179e]*/
5777db96d56Sopenharmony_ci{
5787db96d56Sopenharmony_ci    DWORD n;
5797db96d56Sopenharmony_ci    WCHAR *lpMsgBuf;
5807db96d56Sopenharmony_ci    PyObject *res;
5817db96d56Sopenharmony_ci
5827db96d56Sopenharmony_ci    n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
5837db96d56Sopenharmony_ci                       FORMAT_MESSAGE_FROM_SYSTEM |
5847db96d56Sopenharmony_ci                       FORMAT_MESSAGE_IGNORE_INSERTS,
5857db96d56Sopenharmony_ci                       NULL,
5867db96d56Sopenharmony_ci                       code,
5877db96d56Sopenharmony_ci                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
5887db96d56Sopenharmony_ci                       (LPWSTR) &lpMsgBuf,
5897db96d56Sopenharmony_ci                       0,
5907db96d56Sopenharmony_ci                       NULL);
5917db96d56Sopenharmony_ci    if (n) {
5927db96d56Sopenharmony_ci        while (iswspace(lpMsgBuf[n-1]))
5937db96d56Sopenharmony_ci            --n;
5947db96d56Sopenharmony_ci        lpMsgBuf[n] = L'\0';
5957db96d56Sopenharmony_ci        res = Py_BuildValue("u", lpMsgBuf);
5967db96d56Sopenharmony_ci    } else {
5977db96d56Sopenharmony_ci        res = PyUnicode_FromFormat("unknown error code %u", code);
5987db96d56Sopenharmony_ci    }
5997db96d56Sopenharmony_ci    LocalFree(lpMsgBuf);
6007db96d56Sopenharmony_ci    return res;
6017db96d56Sopenharmony_ci}
6027db96d56Sopenharmony_ci
6037db96d56Sopenharmony_ci
6047db96d56Sopenharmony_ci/*
6057db96d56Sopenharmony_ci * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE
6067db96d56Sopenharmony_ci */
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_cistatic inline void
6097db96d56Sopenharmony_cimark_as_completed(OVERLAPPED *ov)
6107db96d56Sopenharmony_ci{
6117db96d56Sopenharmony_ci    ov->Internal = 0;
6127db96d56Sopenharmony_ci    if (ov->hEvent != NULL)
6137db96d56Sopenharmony_ci        SetEvent(ov->hEvent);
6147db96d56Sopenharmony_ci}
6157db96d56Sopenharmony_ci
6167db96d56Sopenharmony_ci/*
6177db96d56Sopenharmony_ci * A Python object wrapping an OVERLAPPED structure and other useful data
6187db96d56Sopenharmony_ci * for overlapped I/O
6197db96d56Sopenharmony_ci */
6207db96d56Sopenharmony_ci
6217db96d56Sopenharmony_ci/*[clinic input]
6227db96d56Sopenharmony_ci@classmethod
6237db96d56Sopenharmony_ci_overlapped.Overlapped.__new__
6247db96d56Sopenharmony_ci
6257db96d56Sopenharmony_ci    event: HANDLE(c_default='INVALID_HANDLE_VALUE') = _overlapped.INVALID_HANDLE_VALUE
6267db96d56Sopenharmony_ci
6277db96d56Sopenharmony_ciOVERLAPPED structure wrapper.
6287db96d56Sopenharmony_ci[clinic start generated code]*/
6297db96d56Sopenharmony_ci
6307db96d56Sopenharmony_cistatic PyObject *
6317db96d56Sopenharmony_ci_overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event)
6327db96d56Sopenharmony_ci/*[clinic end generated code: output=6da60504a18eb421 input=26b8a7429e629e95]*/
6337db96d56Sopenharmony_ci{
6347db96d56Sopenharmony_ci    OverlappedObject *self;
6357db96d56Sopenharmony_ci
6367db96d56Sopenharmony_ci    if (event == INVALID_HANDLE_VALUE) {
6377db96d56Sopenharmony_ci        event = CreateEvent(NULL, TRUE, FALSE, NULL);
6387db96d56Sopenharmony_ci        if (event == NULL)
6397db96d56Sopenharmony_ci            return SetFromWindowsErr(0);
6407db96d56Sopenharmony_ci    }
6417db96d56Sopenharmony_ci
6427db96d56Sopenharmony_ci    self = PyObject_New(OverlappedObject, type);
6437db96d56Sopenharmony_ci    if (self == NULL) {
6447db96d56Sopenharmony_ci        if (event != NULL)
6457db96d56Sopenharmony_ci            CloseHandle(event);
6467db96d56Sopenharmony_ci        return NULL;
6477db96d56Sopenharmony_ci    }
6487db96d56Sopenharmony_ci
6497db96d56Sopenharmony_ci    self->handle = NULL;
6507db96d56Sopenharmony_ci    self->error = 0;
6517db96d56Sopenharmony_ci    self->type = TYPE_NONE;
6527db96d56Sopenharmony_ci    self->allocated_buffer = NULL;
6537db96d56Sopenharmony_ci    memset(&self->overlapped, 0, sizeof(OVERLAPPED));
6547db96d56Sopenharmony_ci    memset(&self->user_buffer, 0, sizeof(Py_buffer));
6557db96d56Sopenharmony_ci    if (event)
6567db96d56Sopenharmony_ci        self->overlapped.hEvent = event;
6577db96d56Sopenharmony_ci    return (PyObject *)self;
6587db96d56Sopenharmony_ci}
6597db96d56Sopenharmony_ci
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ci/* Note (bpo-32710): OverlappedType.tp_clear is not defined to not release
6627db96d56Sopenharmony_ci   buffers while overlapped are still running, to prevent a crash. */
6637db96d56Sopenharmony_cistatic int
6647db96d56Sopenharmony_ciOverlapped_clear(OverlappedObject *self)
6657db96d56Sopenharmony_ci{
6667db96d56Sopenharmony_ci    switch (self->type) {
6677db96d56Sopenharmony_ci        case TYPE_READ:
6687db96d56Sopenharmony_ci        case TYPE_ACCEPT: {
6697db96d56Sopenharmony_ci            Py_CLEAR(self->allocated_buffer);
6707db96d56Sopenharmony_ci            break;
6717db96d56Sopenharmony_ci        }
6727db96d56Sopenharmony_ci        case TYPE_READ_FROM: {
6737db96d56Sopenharmony_ci            // An initial call to WSARecvFrom will only allocate the buffer.
6747db96d56Sopenharmony_ci            // The result tuple of (message, address) is only
6757db96d56Sopenharmony_ci            // allocated _after_ a message has been received.
6767db96d56Sopenharmony_ci            if(self->read_from.result) {
6777db96d56Sopenharmony_ci                // We've received a message, free the result tuple.
6787db96d56Sopenharmony_ci                Py_CLEAR(self->read_from.result);
6797db96d56Sopenharmony_ci            }
6807db96d56Sopenharmony_ci            if(self->read_from.allocated_buffer) {
6817db96d56Sopenharmony_ci                Py_CLEAR(self->read_from.allocated_buffer);
6827db96d56Sopenharmony_ci            }
6837db96d56Sopenharmony_ci            break;
6847db96d56Sopenharmony_ci        }
6857db96d56Sopenharmony_ci        case TYPE_READ_FROM_INTO: {
6867db96d56Sopenharmony_ci            if (self->read_from_into.result) {
6877db96d56Sopenharmony_ci                // We've received a message, free the result tuple.
6887db96d56Sopenharmony_ci                Py_CLEAR(self->read_from_into.result);
6897db96d56Sopenharmony_ci            }
6907db96d56Sopenharmony_ci            if (self->read_from_into.user_buffer.obj) {
6917db96d56Sopenharmony_ci                PyBuffer_Release(&self->read_from_into.user_buffer);
6927db96d56Sopenharmony_ci            }
6937db96d56Sopenharmony_ci            break;
6947db96d56Sopenharmony_ci        }
6957db96d56Sopenharmony_ci        case TYPE_WRITE:
6967db96d56Sopenharmony_ci        case TYPE_WRITE_TO:
6977db96d56Sopenharmony_ci        case TYPE_READINTO: {
6987db96d56Sopenharmony_ci            if (self->user_buffer.obj) {
6997db96d56Sopenharmony_ci                PyBuffer_Release(&self->user_buffer);
7007db96d56Sopenharmony_ci            }
7017db96d56Sopenharmony_ci            break;
7027db96d56Sopenharmony_ci        }
7037db96d56Sopenharmony_ci    }
7047db96d56Sopenharmony_ci    self->type = TYPE_NOT_STARTED;
7057db96d56Sopenharmony_ci    return 0;
7067db96d56Sopenharmony_ci}
7077db96d56Sopenharmony_ci
7087db96d56Sopenharmony_cistatic void
7097db96d56Sopenharmony_ciOverlapped_dealloc(OverlappedObject *self)
7107db96d56Sopenharmony_ci{
7117db96d56Sopenharmony_ci    DWORD bytes;
7127db96d56Sopenharmony_ci    DWORD olderr = GetLastError();
7137db96d56Sopenharmony_ci    BOOL wait = FALSE;
7147db96d56Sopenharmony_ci    BOOL ret;
7157db96d56Sopenharmony_ci
7167db96d56Sopenharmony_ci    if (!HasOverlappedIoCompleted(&self->overlapped) &&
7177db96d56Sopenharmony_ci        self->type != TYPE_NOT_STARTED)
7187db96d56Sopenharmony_ci    {
7197db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
7207db96d56Sopenharmony_ci        if (CancelIoEx(self->handle, &self->overlapped))
7217db96d56Sopenharmony_ci            wait = TRUE;
7227db96d56Sopenharmony_ci
7237db96d56Sopenharmony_ci        ret = GetOverlappedResult(self->handle, &self->overlapped,
7247db96d56Sopenharmony_ci                                  &bytes, wait);
7257db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
7267db96d56Sopenharmony_ci
7277db96d56Sopenharmony_ci        switch (ret ? ERROR_SUCCESS : GetLastError()) {
7287db96d56Sopenharmony_ci            case ERROR_SUCCESS:
7297db96d56Sopenharmony_ci            case ERROR_NOT_FOUND:
7307db96d56Sopenharmony_ci            case ERROR_OPERATION_ABORTED:
7317db96d56Sopenharmony_ci                break;
7327db96d56Sopenharmony_ci            default:
7337db96d56Sopenharmony_ci                PyErr_Format(
7347db96d56Sopenharmony_ci                    PyExc_RuntimeError,
7357db96d56Sopenharmony_ci                    "%R still has pending operation at "
7367db96d56Sopenharmony_ci                    "deallocation, the process may crash", self);
7377db96d56Sopenharmony_ci                PyErr_WriteUnraisable(NULL);
7387db96d56Sopenharmony_ci        }
7397db96d56Sopenharmony_ci    }
7407db96d56Sopenharmony_ci
7417db96d56Sopenharmony_ci    if (self->overlapped.hEvent != NULL) {
7427db96d56Sopenharmony_ci        CloseHandle(self->overlapped.hEvent);
7437db96d56Sopenharmony_ci    }
7447db96d56Sopenharmony_ci
7457db96d56Sopenharmony_ci    Overlapped_clear(self);
7467db96d56Sopenharmony_ci    SetLastError(olderr);
7477db96d56Sopenharmony_ci
7487db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(self);
7497db96d56Sopenharmony_ci    PyObject_Free(self);
7507db96d56Sopenharmony_ci    Py_DECREF(tp);
7517db96d56Sopenharmony_ci}
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ci
7547db96d56Sopenharmony_ci/* Convert IPv4 sockaddr to a Python str. */
7557db96d56Sopenharmony_ci
7567db96d56Sopenharmony_cistatic PyObject *
7577db96d56Sopenharmony_cimake_ipv4_addr(const struct sockaddr_in *addr)
7587db96d56Sopenharmony_ci{
7597db96d56Sopenharmony_ci        char buf[INET_ADDRSTRLEN];
7607db96d56Sopenharmony_ci        if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) {
7617db96d56Sopenharmony_ci                PyErr_SetFromErrno(PyExc_OSError);
7627db96d56Sopenharmony_ci                return NULL;
7637db96d56Sopenharmony_ci        }
7647db96d56Sopenharmony_ci        return PyUnicode_FromString(buf);
7657db96d56Sopenharmony_ci}
7667db96d56Sopenharmony_ci
7677db96d56Sopenharmony_ci/* Convert IPv6 sockaddr to a Python str. */
7687db96d56Sopenharmony_ci
7697db96d56Sopenharmony_cistatic PyObject *
7707db96d56Sopenharmony_cimake_ipv6_addr(const struct sockaddr_in6 *addr)
7717db96d56Sopenharmony_ci{
7727db96d56Sopenharmony_ci        char buf[INET6_ADDRSTRLEN];
7737db96d56Sopenharmony_ci        if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) {
7747db96d56Sopenharmony_ci                PyErr_SetFromErrno(PyExc_OSError);
7757db96d56Sopenharmony_ci                return NULL;
7767db96d56Sopenharmony_ci        }
7777db96d56Sopenharmony_ci        return PyUnicode_FromString(buf);
7787db96d56Sopenharmony_ci}
7797db96d56Sopenharmony_ci
7807db96d56Sopenharmony_cistatic PyObject*
7817db96d56Sopenharmony_ciunparse_address(LPSOCKADDR Address, DWORD Length)
7827db96d56Sopenharmony_ci{
7837db96d56Sopenharmony_ci        /* The function is adopted from mocketmodule.c makesockaddr()*/
7847db96d56Sopenharmony_ci
7857db96d56Sopenharmony_ci    switch(Address->sa_family) {
7867db96d56Sopenharmony_ci        case AF_INET: {
7877db96d56Sopenharmony_ci            const struct sockaddr_in *a = (const struct sockaddr_in *)Address;
7887db96d56Sopenharmony_ci            PyObject *addrobj = make_ipv4_addr(a);
7897db96d56Sopenharmony_ci            PyObject *ret = NULL;
7907db96d56Sopenharmony_ci            if (addrobj) {
7917db96d56Sopenharmony_ci                ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
7927db96d56Sopenharmony_ci                Py_DECREF(addrobj);
7937db96d56Sopenharmony_ci            }
7947db96d56Sopenharmony_ci            return ret;
7957db96d56Sopenharmony_ci        }
7967db96d56Sopenharmony_ci        case AF_INET6: {
7977db96d56Sopenharmony_ci            const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)Address;
7987db96d56Sopenharmony_ci            PyObject *addrobj = make_ipv6_addr(a);
7997db96d56Sopenharmony_ci            PyObject *ret = NULL;
8007db96d56Sopenharmony_ci            if (addrobj) {
8017db96d56Sopenharmony_ci                ret = Py_BuildValue("OiII",
8027db96d56Sopenharmony_ci                                    addrobj,
8037db96d56Sopenharmony_ci                                    ntohs(a->sin6_port),
8047db96d56Sopenharmony_ci                                    ntohl(a->sin6_flowinfo),
8057db96d56Sopenharmony_ci                                    a->sin6_scope_id);
8067db96d56Sopenharmony_ci                Py_DECREF(addrobj);
8077db96d56Sopenharmony_ci            }
8087db96d56Sopenharmony_ci            return ret;
8097db96d56Sopenharmony_ci        }
8107db96d56Sopenharmony_ci        default: {
8117db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError, "recvfrom returned unsupported address family");
8127db96d56Sopenharmony_ci            return NULL;
8137db96d56Sopenharmony_ci        }
8147db96d56Sopenharmony_ci    }
8157db96d56Sopenharmony_ci}
8167db96d56Sopenharmony_ci
8177db96d56Sopenharmony_ci/*[clinic input]
8187db96d56Sopenharmony_ci_overlapped.Overlapped.cancel
8197db96d56Sopenharmony_ci
8207db96d56Sopenharmony_ciCancel overlapped operation.
8217db96d56Sopenharmony_ci[clinic start generated code]*/
8227db96d56Sopenharmony_ci
8237db96d56Sopenharmony_cistatic PyObject *
8247db96d56Sopenharmony_ci_overlapped_Overlapped_cancel_impl(OverlappedObject *self)
8257db96d56Sopenharmony_ci/*[clinic end generated code: output=54ad7aeece89901c input=80eb67c7b57dbcf1]*/
8267db96d56Sopenharmony_ci{
8277db96d56Sopenharmony_ci    BOOL ret = TRUE;
8287db96d56Sopenharmony_ci
8297db96d56Sopenharmony_ci    if (self->type == TYPE_NOT_STARTED
8307db96d56Sopenharmony_ci        || self->type == TYPE_WAIT_NAMED_PIPE_AND_CONNECT)
8317db96d56Sopenharmony_ci        Py_RETURN_NONE;
8327db96d56Sopenharmony_ci
8337db96d56Sopenharmony_ci    if (!HasOverlappedIoCompleted(&self->overlapped)) {
8347db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
8357db96d56Sopenharmony_ci        ret = CancelIoEx(self->handle, &self->overlapped);
8367db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
8377db96d56Sopenharmony_ci    }
8387db96d56Sopenharmony_ci
8397db96d56Sopenharmony_ci    /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */
8407db96d56Sopenharmony_ci    if (!ret && GetLastError() != ERROR_NOT_FOUND)
8417db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
8427db96d56Sopenharmony_ci    Py_RETURN_NONE;
8437db96d56Sopenharmony_ci}
8447db96d56Sopenharmony_ci
8457db96d56Sopenharmony_ci/*[clinic input]
8467db96d56Sopenharmony_ci_overlapped.Overlapped.getresult
8477db96d56Sopenharmony_ci
8487db96d56Sopenharmony_ci    wait: BOOL(c_default='FALSE') = False
8497db96d56Sopenharmony_ci    /
8507db96d56Sopenharmony_ci
8517db96d56Sopenharmony_ciRetrieve result of operation.
8527db96d56Sopenharmony_ci
8537db96d56Sopenharmony_ciIf wait is true then it blocks until the operation is finished.  If wait
8547db96d56Sopenharmony_ciis false and the operation is still pending then an error is raised.
8557db96d56Sopenharmony_ci[clinic start generated code]*/
8567db96d56Sopenharmony_ci
8577db96d56Sopenharmony_cistatic PyObject *
8587db96d56Sopenharmony_ci_overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait)
8597db96d56Sopenharmony_ci/*[clinic end generated code: output=8c9bd04d08994f6c input=aa5b03e9897ca074]*/
8607db96d56Sopenharmony_ci{
8617db96d56Sopenharmony_ci    DWORD transferred = 0;
8627db96d56Sopenharmony_ci    BOOL ret;
8637db96d56Sopenharmony_ci    DWORD err;
8647db96d56Sopenharmony_ci    PyObject *addr;
8657db96d56Sopenharmony_ci
8667db96d56Sopenharmony_ci    if (self->type == TYPE_NONE) {
8677db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation not yet attempted");
8687db96d56Sopenharmony_ci        return NULL;
8697db96d56Sopenharmony_ci    }
8707db96d56Sopenharmony_ci
8717db96d56Sopenharmony_ci    if (self->type == TYPE_NOT_STARTED) {
8727db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation failed to start");
8737db96d56Sopenharmony_ci        return NULL;
8747db96d56Sopenharmony_ci    }
8757db96d56Sopenharmony_ci
8767db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
8777db96d56Sopenharmony_ci    ret = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
8787db96d56Sopenharmony_ci                              wait);
8797db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
8807db96d56Sopenharmony_ci
8817db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
8827db96d56Sopenharmony_ci    switch (err) {
8837db96d56Sopenharmony_ci        case ERROR_SUCCESS:
8847db96d56Sopenharmony_ci        case ERROR_MORE_DATA:
8857db96d56Sopenharmony_ci            break;
8867db96d56Sopenharmony_ci        case ERROR_BROKEN_PIPE:
8877db96d56Sopenharmony_ci            if (self->type == TYPE_READ || self->type == TYPE_READINTO) {
8887db96d56Sopenharmony_ci                break;
8897db96d56Sopenharmony_ci            }
8907db96d56Sopenharmony_ci            else if (self->type == TYPE_READ_FROM &&
8917db96d56Sopenharmony_ci                     (self->read_from.result != NULL ||
8927db96d56Sopenharmony_ci                      self->read_from.allocated_buffer != NULL))
8937db96d56Sopenharmony_ci            {
8947db96d56Sopenharmony_ci                break;
8957db96d56Sopenharmony_ci            }
8967db96d56Sopenharmony_ci            else if (self->type == TYPE_READ_FROM_INTO &&
8977db96d56Sopenharmony_ci                     self->read_from_into.result != NULL)
8987db96d56Sopenharmony_ci            {
8997db96d56Sopenharmony_ci                break;
9007db96d56Sopenharmony_ci            }
9017db96d56Sopenharmony_ci            /* fall through */
9027db96d56Sopenharmony_ci        default:
9037db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
9047db96d56Sopenharmony_ci    }
9057db96d56Sopenharmony_ci
9067db96d56Sopenharmony_ci    switch (self->type) {
9077db96d56Sopenharmony_ci        case TYPE_READ:
9087db96d56Sopenharmony_ci            assert(PyBytes_CheckExact(self->allocated_buffer));
9097db96d56Sopenharmony_ci            if (transferred != PyBytes_GET_SIZE(self->allocated_buffer) &&
9107db96d56Sopenharmony_ci                _PyBytes_Resize(&self->allocated_buffer, transferred))
9117db96d56Sopenharmony_ci                return NULL;
9127db96d56Sopenharmony_ci
9137db96d56Sopenharmony_ci            Py_INCREF(self->allocated_buffer);
9147db96d56Sopenharmony_ci            return self->allocated_buffer;
9157db96d56Sopenharmony_ci        case TYPE_READ_FROM:
9167db96d56Sopenharmony_ci            assert(PyBytes_CheckExact(self->read_from.allocated_buffer));
9177db96d56Sopenharmony_ci
9187db96d56Sopenharmony_ci            if (transferred != PyBytes_GET_SIZE(
9197db96d56Sopenharmony_ci                    self->read_from.allocated_buffer) &&
9207db96d56Sopenharmony_ci                _PyBytes_Resize(&self->read_from.allocated_buffer, transferred))
9217db96d56Sopenharmony_ci            {
9227db96d56Sopenharmony_ci                return NULL;
9237db96d56Sopenharmony_ci            }
9247db96d56Sopenharmony_ci
9257db96d56Sopenharmony_ci            // unparse the address
9267db96d56Sopenharmony_ci            addr = unparse_address((SOCKADDR*)&self->read_from.address,
9277db96d56Sopenharmony_ci                                   self->read_from.address_length);
9287db96d56Sopenharmony_ci
9297db96d56Sopenharmony_ci            if (addr == NULL) {
9307db96d56Sopenharmony_ci                return NULL;
9317db96d56Sopenharmony_ci            }
9327db96d56Sopenharmony_ci
9337db96d56Sopenharmony_ci            // The result is a two item tuple: (message, address)
9347db96d56Sopenharmony_ci            self->read_from.result = PyTuple_New(2);
9357db96d56Sopenharmony_ci            if (self->read_from.result == NULL) {
9367db96d56Sopenharmony_ci                Py_CLEAR(addr);
9377db96d56Sopenharmony_ci                return NULL;
9387db96d56Sopenharmony_ci            }
9397db96d56Sopenharmony_ci
9407db96d56Sopenharmony_ci            // first item: message
9417db96d56Sopenharmony_ci            Py_INCREF(self->read_from.allocated_buffer);
9427db96d56Sopenharmony_ci            PyTuple_SET_ITEM(self->read_from.result, 0,
9437db96d56Sopenharmony_ci                             self->read_from.allocated_buffer);
9447db96d56Sopenharmony_ci            // second item: address
9457db96d56Sopenharmony_ci            PyTuple_SET_ITEM(self->read_from.result, 1, addr);
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci            Py_INCREF(self->read_from.result);
9487db96d56Sopenharmony_ci            return self->read_from.result;
9497db96d56Sopenharmony_ci        case TYPE_READ_FROM_INTO:
9507db96d56Sopenharmony_ci            // unparse the address
9517db96d56Sopenharmony_ci            addr = unparse_address((SOCKADDR*)&self->read_from_into.address,
9527db96d56Sopenharmony_ci                self->read_from_into.address_length);
9537db96d56Sopenharmony_ci
9547db96d56Sopenharmony_ci            if (addr == NULL) {
9557db96d56Sopenharmony_ci                return NULL;
9567db96d56Sopenharmony_ci            }
9577db96d56Sopenharmony_ci
9587db96d56Sopenharmony_ci            // The result is a two item tuple: (number of bytes read, address)
9597db96d56Sopenharmony_ci            self->read_from_into.result = PyTuple_New(2);
9607db96d56Sopenharmony_ci            if (self->read_from_into.result == NULL) {
9617db96d56Sopenharmony_ci                Py_CLEAR(addr);
9627db96d56Sopenharmony_ci                return NULL;
9637db96d56Sopenharmony_ci            }
9647db96d56Sopenharmony_ci
9657db96d56Sopenharmony_ci            // first item: number of bytes read
9667db96d56Sopenharmony_ci            PyTuple_SET_ITEM(self->read_from_into.result, 0,
9677db96d56Sopenharmony_ci                PyLong_FromUnsignedLong((unsigned long)transferred));
9687db96d56Sopenharmony_ci            // second item: address
9697db96d56Sopenharmony_ci            PyTuple_SET_ITEM(self->read_from_into.result, 1, addr);
9707db96d56Sopenharmony_ci
9717db96d56Sopenharmony_ci            Py_INCREF(self->read_from_into.result);
9727db96d56Sopenharmony_ci            return self->read_from_into.result;
9737db96d56Sopenharmony_ci        default:
9747db96d56Sopenharmony_ci            return PyLong_FromUnsignedLong((unsigned long) transferred);
9757db96d56Sopenharmony_ci    }
9767db96d56Sopenharmony_ci}
9777db96d56Sopenharmony_ci
9787db96d56Sopenharmony_cistatic PyObject *
9797db96d56Sopenharmony_cido_ReadFile(OverlappedObject *self, HANDLE handle,
9807db96d56Sopenharmony_ci            char *bufstart, DWORD buflen)
9817db96d56Sopenharmony_ci{
9827db96d56Sopenharmony_ci    DWORD nread;
9837db96d56Sopenharmony_ci    int ret;
9847db96d56Sopenharmony_ci    DWORD err;
9857db96d56Sopenharmony_ci
9867db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
9877db96d56Sopenharmony_ci    ret = ReadFile(handle, bufstart, buflen, &nread,
9887db96d56Sopenharmony_ci                   &self->overlapped);
9897db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
9907db96d56Sopenharmony_ci
9917db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
9927db96d56Sopenharmony_ci    switch (err) {
9937db96d56Sopenharmony_ci        case ERROR_BROKEN_PIPE:
9947db96d56Sopenharmony_ci            mark_as_completed(&self->overlapped);
9957db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
9967db96d56Sopenharmony_ci        case ERROR_SUCCESS:
9977db96d56Sopenharmony_ci        case ERROR_MORE_DATA:
9987db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
9997db96d56Sopenharmony_ci            Py_RETURN_NONE;
10007db96d56Sopenharmony_ci        default:
10017db96d56Sopenharmony_ci            Overlapped_clear(self);
10027db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
10037db96d56Sopenharmony_ci    }
10047db96d56Sopenharmony_ci}
10057db96d56Sopenharmony_ci
10067db96d56Sopenharmony_ci/*[clinic input]
10077db96d56Sopenharmony_ci_overlapped.Overlapped.ReadFile
10087db96d56Sopenharmony_ci
10097db96d56Sopenharmony_ci    handle: HANDLE
10107db96d56Sopenharmony_ci    size: DWORD
10117db96d56Sopenharmony_ci    /
10127db96d56Sopenharmony_ci
10137db96d56Sopenharmony_ciStart overlapped read.
10147db96d56Sopenharmony_ci[clinic start generated code]*/
10157db96d56Sopenharmony_ci
10167db96d56Sopenharmony_cistatic PyObject *
10177db96d56Sopenharmony_ci_overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle,
10187db96d56Sopenharmony_ci                                     DWORD size)
10197db96d56Sopenharmony_ci/*[clinic end generated code: output=4c8557e16941e4ae input=98c495baa0342425]*/
10207db96d56Sopenharmony_ci{
10217db96d56Sopenharmony_ci    PyObject *buf;
10227db96d56Sopenharmony_ci
10237db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
10247db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
10257db96d56Sopenharmony_ci        return NULL;
10267db96d56Sopenharmony_ci    }
10277db96d56Sopenharmony_ci
10287db96d56Sopenharmony_ci#if SIZEOF_SIZE_T <= SIZEOF_LONG
10297db96d56Sopenharmony_ci    size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
10307db96d56Sopenharmony_ci#endif
10317db96d56Sopenharmony_ci    buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
10327db96d56Sopenharmony_ci    if (buf == NULL)
10337db96d56Sopenharmony_ci        return NULL;
10347db96d56Sopenharmony_ci
10357db96d56Sopenharmony_ci    self->type = TYPE_READ;
10367db96d56Sopenharmony_ci    self->handle = handle;
10377db96d56Sopenharmony_ci    self->allocated_buffer = buf;
10387db96d56Sopenharmony_ci
10397db96d56Sopenharmony_ci    return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size);
10407db96d56Sopenharmony_ci}
10417db96d56Sopenharmony_ci
10427db96d56Sopenharmony_ci/*[clinic input]
10437db96d56Sopenharmony_ci_overlapped.Overlapped.ReadFileInto
10447db96d56Sopenharmony_ci
10457db96d56Sopenharmony_ci    handle: HANDLE
10467db96d56Sopenharmony_ci    buf as bufobj: Py_buffer
10477db96d56Sopenharmony_ci    /
10487db96d56Sopenharmony_ci
10497db96d56Sopenharmony_ciStart overlapped receive.
10507db96d56Sopenharmony_ci[clinic start generated code]*/
10517db96d56Sopenharmony_ci
10527db96d56Sopenharmony_cistatic PyObject *
10537db96d56Sopenharmony_ci_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self,
10547db96d56Sopenharmony_ci                                         HANDLE handle, Py_buffer *bufobj)
10557db96d56Sopenharmony_ci/*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/
10567db96d56Sopenharmony_ci{
10577db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
10587db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
10597db96d56Sopenharmony_ci        return NULL;
10607db96d56Sopenharmony_ci    }
10617db96d56Sopenharmony_ci
10627db96d56Sopenharmony_ci#if SIZEOF_SIZE_T > SIZEOF_LONG
10637db96d56Sopenharmony_ci    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
10647db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "buffer too large");
10657db96d56Sopenharmony_ci        return NULL;
10667db96d56Sopenharmony_ci    }
10677db96d56Sopenharmony_ci#endif
10687db96d56Sopenharmony_ci    steal_buffer(&self->user_buffer, bufobj);
10697db96d56Sopenharmony_ci
10707db96d56Sopenharmony_ci    self->type = TYPE_READINTO;
10717db96d56Sopenharmony_ci    self->handle = handle;
10727db96d56Sopenharmony_ci
10737db96d56Sopenharmony_ci    return do_ReadFile(self, handle, self->user_buffer.buf,
10747db96d56Sopenharmony_ci                       (DWORD)self->user_buffer.len);
10757db96d56Sopenharmony_ci}
10767db96d56Sopenharmony_ci
10777db96d56Sopenharmony_cistatic PyObject *
10787db96d56Sopenharmony_cido_WSARecv(OverlappedObject *self, HANDLE handle,
10797db96d56Sopenharmony_ci           char *bufstart, DWORD buflen, DWORD flags)
10807db96d56Sopenharmony_ci{
10817db96d56Sopenharmony_ci    DWORD nread;
10827db96d56Sopenharmony_ci    WSABUF wsabuf;
10837db96d56Sopenharmony_ci    int ret;
10847db96d56Sopenharmony_ci    DWORD err;
10857db96d56Sopenharmony_ci
10867db96d56Sopenharmony_ci    wsabuf.buf = bufstart;
10877db96d56Sopenharmony_ci    wsabuf.len = buflen;
10887db96d56Sopenharmony_ci
10897db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
10907db96d56Sopenharmony_ci    ret = WSARecv((SOCKET)handle, &wsabuf, 1, &nread, &flags,
10917db96d56Sopenharmony_ci                  &self->overlapped, NULL);
10927db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
10937db96d56Sopenharmony_ci
10947db96d56Sopenharmony_ci    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
10957db96d56Sopenharmony_ci    switch (err) {
10967db96d56Sopenharmony_ci        case ERROR_BROKEN_PIPE:
10977db96d56Sopenharmony_ci            mark_as_completed(&self->overlapped);
10987db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
10997db96d56Sopenharmony_ci        case ERROR_SUCCESS:
11007db96d56Sopenharmony_ci        case ERROR_MORE_DATA:
11017db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
11027db96d56Sopenharmony_ci            Py_RETURN_NONE;
11037db96d56Sopenharmony_ci        default:
11047db96d56Sopenharmony_ci            Overlapped_clear(self);
11057db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
11067db96d56Sopenharmony_ci    }
11077db96d56Sopenharmony_ci}
11087db96d56Sopenharmony_ci
11097db96d56Sopenharmony_ci
11107db96d56Sopenharmony_ci/*[clinic input]
11117db96d56Sopenharmony_ci_overlapped.Overlapped.WSARecv
11127db96d56Sopenharmony_ci
11137db96d56Sopenharmony_ci    handle: HANDLE
11147db96d56Sopenharmony_ci    size: DWORD
11157db96d56Sopenharmony_ci    flags: DWORD = 0
11167db96d56Sopenharmony_ci    /
11177db96d56Sopenharmony_ci
11187db96d56Sopenharmony_ciStart overlapped receive.
11197db96d56Sopenharmony_ci[clinic start generated code]*/
11207db96d56Sopenharmony_ci
11217db96d56Sopenharmony_cistatic PyObject *
11227db96d56Sopenharmony_ci_overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle,
11237db96d56Sopenharmony_ci                                    DWORD size, DWORD flags)
11247db96d56Sopenharmony_ci/*[clinic end generated code: output=3a5e9c61ff040906 input=8c04e506cc3d741a]*/
11257db96d56Sopenharmony_ci{
11267db96d56Sopenharmony_ci    PyObject *buf;
11277db96d56Sopenharmony_ci
11287db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
11297db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
11307db96d56Sopenharmony_ci        return NULL;
11317db96d56Sopenharmony_ci    }
11327db96d56Sopenharmony_ci
11337db96d56Sopenharmony_ci#if SIZEOF_SIZE_T <= SIZEOF_LONG
11347db96d56Sopenharmony_ci    size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
11357db96d56Sopenharmony_ci#endif
11367db96d56Sopenharmony_ci    buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
11377db96d56Sopenharmony_ci    if (buf == NULL)
11387db96d56Sopenharmony_ci        return NULL;
11397db96d56Sopenharmony_ci
11407db96d56Sopenharmony_ci    self->type = TYPE_READ;
11417db96d56Sopenharmony_ci    self->handle = handle;
11427db96d56Sopenharmony_ci    self->allocated_buffer = buf;
11437db96d56Sopenharmony_ci
11447db96d56Sopenharmony_ci    return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags);
11457db96d56Sopenharmony_ci}
11467db96d56Sopenharmony_ci
11477db96d56Sopenharmony_ci/*[clinic input]
11487db96d56Sopenharmony_ci_overlapped.Overlapped.WSARecvInto
11497db96d56Sopenharmony_ci
11507db96d56Sopenharmony_ci    handle: HANDLE
11517db96d56Sopenharmony_ci    buf as bufobj: Py_buffer
11527db96d56Sopenharmony_ci    flags: DWORD
11537db96d56Sopenharmony_ci    /
11547db96d56Sopenharmony_ci
11557db96d56Sopenharmony_ciStart overlapped receive.
11567db96d56Sopenharmony_ci[clinic start generated code]*/
11577db96d56Sopenharmony_ci
11587db96d56Sopenharmony_cistatic PyObject *
11597db96d56Sopenharmony_ci_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
11607db96d56Sopenharmony_ci                                        HANDLE handle, Py_buffer *bufobj,
11617db96d56Sopenharmony_ci                                        DWORD flags)
11627db96d56Sopenharmony_ci/*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/
11637db96d56Sopenharmony_ci{
11647db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
11657db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
11667db96d56Sopenharmony_ci        return NULL;
11677db96d56Sopenharmony_ci    }
11687db96d56Sopenharmony_ci
11697db96d56Sopenharmony_ci#if SIZEOF_SIZE_T > SIZEOF_LONG
11707db96d56Sopenharmony_ci    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
11717db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "buffer too large");
11727db96d56Sopenharmony_ci        return NULL;
11737db96d56Sopenharmony_ci    }
11747db96d56Sopenharmony_ci#endif
11757db96d56Sopenharmony_ci    steal_buffer(&self->user_buffer, bufobj);
11767db96d56Sopenharmony_ci
11777db96d56Sopenharmony_ci    self->type = TYPE_READINTO;
11787db96d56Sopenharmony_ci    self->handle = handle;
11797db96d56Sopenharmony_ci
11807db96d56Sopenharmony_ci    return do_WSARecv(self, handle, self->user_buffer.buf,
11817db96d56Sopenharmony_ci                      (DWORD)self->user_buffer.len, flags);
11827db96d56Sopenharmony_ci}
11837db96d56Sopenharmony_ci
11847db96d56Sopenharmony_ci/*[clinic input]
11857db96d56Sopenharmony_ci_overlapped.Overlapped.WriteFile
11867db96d56Sopenharmony_ci
11877db96d56Sopenharmony_ci    handle: HANDLE
11887db96d56Sopenharmony_ci    buf as bufobj: Py_buffer
11897db96d56Sopenharmony_ci    /
11907db96d56Sopenharmony_ci
11917db96d56Sopenharmony_ciStart overlapped write.
11927db96d56Sopenharmony_ci[clinic start generated code]*/
11937db96d56Sopenharmony_ci
11947db96d56Sopenharmony_cistatic PyObject *
11957db96d56Sopenharmony_ci_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
11967db96d56Sopenharmony_ci                                      Py_buffer *bufobj)
11977db96d56Sopenharmony_ci/*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/
11987db96d56Sopenharmony_ci{
11997db96d56Sopenharmony_ci    DWORD written;
12007db96d56Sopenharmony_ci    BOOL ret;
12017db96d56Sopenharmony_ci    DWORD err;
12027db96d56Sopenharmony_ci
12037db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
12047db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
12057db96d56Sopenharmony_ci        return NULL;
12067db96d56Sopenharmony_ci    }
12077db96d56Sopenharmony_ci
12087db96d56Sopenharmony_ci#if SIZEOF_SIZE_T > SIZEOF_LONG
12097db96d56Sopenharmony_ci    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
12107db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "buffer too large");
12117db96d56Sopenharmony_ci        return NULL;
12127db96d56Sopenharmony_ci    }
12137db96d56Sopenharmony_ci#endif
12147db96d56Sopenharmony_ci    steal_buffer(&self->user_buffer, bufobj);
12157db96d56Sopenharmony_ci
12167db96d56Sopenharmony_ci    self->type = TYPE_WRITE;
12177db96d56Sopenharmony_ci    self->handle = handle;
12187db96d56Sopenharmony_ci
12197db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
12207db96d56Sopenharmony_ci    ret = WriteFile(handle, self->user_buffer.buf,
12217db96d56Sopenharmony_ci                    (DWORD)self->user_buffer.len,
12227db96d56Sopenharmony_ci                    &written, &self->overlapped);
12237db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
12247db96d56Sopenharmony_ci
12257db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
12267db96d56Sopenharmony_ci    switch (err) {
12277db96d56Sopenharmony_ci        case ERROR_SUCCESS:
12287db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
12297db96d56Sopenharmony_ci            Py_RETURN_NONE;
12307db96d56Sopenharmony_ci        default:
12317db96d56Sopenharmony_ci            Overlapped_clear(self);
12327db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
12337db96d56Sopenharmony_ci    }
12347db96d56Sopenharmony_ci}
12357db96d56Sopenharmony_ci
12367db96d56Sopenharmony_ci/*[clinic input]
12377db96d56Sopenharmony_ci_overlapped.Overlapped.WSASend
12387db96d56Sopenharmony_ci
12397db96d56Sopenharmony_ci    handle: HANDLE
12407db96d56Sopenharmony_ci    buf as bufobj: Py_buffer
12417db96d56Sopenharmony_ci    flags: DWORD
12427db96d56Sopenharmony_ci    /
12437db96d56Sopenharmony_ci
12447db96d56Sopenharmony_ciStart overlapped send.
12457db96d56Sopenharmony_ci[clinic start generated code]*/
12467db96d56Sopenharmony_ci
12477db96d56Sopenharmony_cistatic PyObject *
12487db96d56Sopenharmony_ci_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
12497db96d56Sopenharmony_ci                                    Py_buffer *bufobj, DWORD flags)
12507db96d56Sopenharmony_ci/*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/
12517db96d56Sopenharmony_ci{
12527db96d56Sopenharmony_ci    DWORD written;
12537db96d56Sopenharmony_ci    WSABUF wsabuf;
12547db96d56Sopenharmony_ci    int ret;
12557db96d56Sopenharmony_ci    DWORD err;
12567db96d56Sopenharmony_ci
12577db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
12587db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
12597db96d56Sopenharmony_ci        return NULL;
12607db96d56Sopenharmony_ci    }
12617db96d56Sopenharmony_ci
12627db96d56Sopenharmony_ci#if SIZEOF_SIZE_T > SIZEOF_LONG
12637db96d56Sopenharmony_ci    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
12647db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "buffer too large");
12657db96d56Sopenharmony_ci        return NULL;
12667db96d56Sopenharmony_ci    }
12677db96d56Sopenharmony_ci#endif
12687db96d56Sopenharmony_ci    steal_buffer(&self->user_buffer, bufobj);
12697db96d56Sopenharmony_ci
12707db96d56Sopenharmony_ci    self->type = TYPE_WRITE;
12717db96d56Sopenharmony_ci    self->handle = handle;
12727db96d56Sopenharmony_ci    wsabuf.len = (DWORD)self->user_buffer.len;
12737db96d56Sopenharmony_ci    wsabuf.buf = self->user_buffer.buf;
12747db96d56Sopenharmony_ci
12757db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
12767db96d56Sopenharmony_ci    ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags,
12777db96d56Sopenharmony_ci                  &self->overlapped, NULL);
12787db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
12797db96d56Sopenharmony_ci
12807db96d56Sopenharmony_ci    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
12817db96d56Sopenharmony_ci    switch (err) {
12827db96d56Sopenharmony_ci        case ERROR_SUCCESS:
12837db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
12847db96d56Sopenharmony_ci            Py_RETURN_NONE;
12857db96d56Sopenharmony_ci        default:
12867db96d56Sopenharmony_ci            Overlapped_clear(self);
12877db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
12887db96d56Sopenharmony_ci    }
12897db96d56Sopenharmony_ci}
12907db96d56Sopenharmony_ci
12917db96d56Sopenharmony_ci/*[clinic input]
12927db96d56Sopenharmony_ci_overlapped.Overlapped.AcceptEx
12937db96d56Sopenharmony_ci
12947db96d56Sopenharmony_ci    listen_handle as ListenSocket: HANDLE
12957db96d56Sopenharmony_ci    accept_handle as AcceptSocket: HANDLE
12967db96d56Sopenharmony_ci    /
12977db96d56Sopenharmony_ci
12987db96d56Sopenharmony_ciStart overlapped wait for client to connect.
12997db96d56Sopenharmony_ci[clinic start generated code]*/
13007db96d56Sopenharmony_ci
13017db96d56Sopenharmony_cistatic PyObject *
13027db96d56Sopenharmony_ci_overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self,
13037db96d56Sopenharmony_ci                                     HANDLE ListenSocket,
13047db96d56Sopenharmony_ci                                     HANDLE AcceptSocket)
13057db96d56Sopenharmony_ci/*[clinic end generated code: output=9a7381d4232af889 input=b83473224fc3a1c5]*/
13067db96d56Sopenharmony_ci{
13077db96d56Sopenharmony_ci    DWORD BytesReceived;
13087db96d56Sopenharmony_ci    DWORD size;
13097db96d56Sopenharmony_ci    PyObject *buf;
13107db96d56Sopenharmony_ci    BOOL ret;
13117db96d56Sopenharmony_ci    DWORD err;
13127db96d56Sopenharmony_ci
13137db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
13147db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
13157db96d56Sopenharmony_ci        return NULL;
13167db96d56Sopenharmony_ci    }
13177db96d56Sopenharmony_ci
13187db96d56Sopenharmony_ci    size = sizeof(struct sockaddr_in6) + 16;
13197db96d56Sopenharmony_ci    buf = PyBytes_FromStringAndSize(NULL, size*2);
13207db96d56Sopenharmony_ci    if (!buf)
13217db96d56Sopenharmony_ci        return NULL;
13227db96d56Sopenharmony_ci
13237db96d56Sopenharmony_ci    self->type = TYPE_ACCEPT;
13247db96d56Sopenharmony_ci    self->handle = ListenSocket;
13257db96d56Sopenharmony_ci    self->allocated_buffer = buf;
13267db96d56Sopenharmony_ci
13277db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
13287db96d56Sopenharmony_ci    ret = Py_AcceptEx((SOCKET)ListenSocket, (SOCKET)AcceptSocket,
13297db96d56Sopenharmony_ci                      PyBytes_AS_STRING(buf), 0, size, size, &BytesReceived,
13307db96d56Sopenharmony_ci                      &self->overlapped);
13317db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
13327db96d56Sopenharmony_ci
13337db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
13347db96d56Sopenharmony_ci    switch (err) {
13357db96d56Sopenharmony_ci        case ERROR_SUCCESS:
13367db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
13377db96d56Sopenharmony_ci            Py_RETURN_NONE;
13387db96d56Sopenharmony_ci        default:
13397db96d56Sopenharmony_ci            Overlapped_clear(self);
13407db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
13417db96d56Sopenharmony_ci    }
13427db96d56Sopenharmony_ci}
13437db96d56Sopenharmony_ci
13447db96d56Sopenharmony_ci
13457db96d56Sopenharmony_cistatic int
13467db96d56Sopenharmony_ciparse_address(PyObject *obj, SOCKADDR *Address, int Length)
13477db96d56Sopenharmony_ci{
13487db96d56Sopenharmony_ci    PyObject *Host_obj;
13497db96d56Sopenharmony_ci    Py_UNICODE *Host;
13507db96d56Sopenharmony_ci    unsigned short Port;
13517db96d56Sopenharmony_ci    unsigned long FlowInfo;
13527db96d56Sopenharmony_ci    unsigned long ScopeId;
13537db96d56Sopenharmony_ci
13547db96d56Sopenharmony_ci    memset(Address, 0, Length);
13557db96d56Sopenharmony_ci
13567db96d56Sopenharmony_ci    switch (PyTuple_GET_SIZE(obj)) {
13577db96d56Sopenharmony_ci    case 2: {
13587db96d56Sopenharmony_ci        if (!PyArg_ParseTuple(obj, "UH", &Host_obj, &Port)) {
13597db96d56Sopenharmony_ci            return -1;
13607db96d56Sopenharmony_ci        }
13617db96d56Sopenharmony_ci#if USE_UNICODE_WCHAR_CACHE
13627db96d56Sopenharmony_ci        Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj);
13637db96d56Sopenharmony_ci#else /* USE_UNICODE_WCHAR_CACHE */
13647db96d56Sopenharmony_ci        Host = PyUnicode_AsWideCharString(Host_obj, NULL);
13657db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */
13667db96d56Sopenharmony_ci        if (Host == NULL) {
13677db96d56Sopenharmony_ci            return -1;
13687db96d56Sopenharmony_ci        }
13697db96d56Sopenharmony_ci        Address->sa_family = AF_INET;
13707db96d56Sopenharmony_ci        if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) {
13717db96d56Sopenharmony_ci            SetFromWindowsErr(WSAGetLastError());
13727db96d56Sopenharmony_ci            Length = -1;
13737db96d56Sopenharmony_ci        }
13747db96d56Sopenharmony_ci        else {
13757db96d56Sopenharmony_ci            ((SOCKADDR_IN*)Address)->sin_port = htons(Port);
13767db96d56Sopenharmony_ci        }
13777db96d56Sopenharmony_ci#if !USE_UNICODE_WCHAR_CACHE
13787db96d56Sopenharmony_ci        PyMem_Free(Host);
13797db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */
13807db96d56Sopenharmony_ci        return Length;
13817db96d56Sopenharmony_ci    }
13827db96d56Sopenharmony_ci    case 4: {
13837db96d56Sopenharmony_ci        if (!PyArg_ParseTuple(obj,
13847db96d56Sopenharmony_ci                "UHkk;ConnectEx(): illegal address_as_bytes argument",
13857db96d56Sopenharmony_ci                &Host_obj, &Port, &FlowInfo, &ScopeId))
13867db96d56Sopenharmony_ci        {
13877db96d56Sopenharmony_ci            return -1;
13887db96d56Sopenharmony_ci        }
13897db96d56Sopenharmony_ci#if USE_UNICODE_WCHAR_CACHE
13907db96d56Sopenharmony_ci        Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj);
13917db96d56Sopenharmony_ci#else /* USE_UNICODE_WCHAR_CACHE */
13927db96d56Sopenharmony_ci        Host = PyUnicode_AsWideCharString(Host_obj, NULL);
13937db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */
13947db96d56Sopenharmony_ci        if (Host == NULL) {
13957db96d56Sopenharmony_ci            return -1;
13967db96d56Sopenharmony_ci        }
13977db96d56Sopenharmony_ci        Address->sa_family = AF_INET6;
13987db96d56Sopenharmony_ci        if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) {
13997db96d56Sopenharmony_ci            SetFromWindowsErr(WSAGetLastError());
14007db96d56Sopenharmony_ci            Length = -1;
14017db96d56Sopenharmony_ci        }
14027db96d56Sopenharmony_ci        else {
14037db96d56Sopenharmony_ci            ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port);
14047db96d56Sopenharmony_ci            ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo;
14057db96d56Sopenharmony_ci            ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId;
14067db96d56Sopenharmony_ci        }
14077db96d56Sopenharmony_ci#if !USE_UNICODE_WCHAR_CACHE
14087db96d56Sopenharmony_ci        PyMem_Free(Host);
14097db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */
14107db96d56Sopenharmony_ci        return Length;
14117db96d56Sopenharmony_ci    }
14127db96d56Sopenharmony_ci    default:
14137db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "illegal address_as_bytes argument");
14147db96d56Sopenharmony_ci        return -1;
14157db96d56Sopenharmony_ci    }
14167db96d56Sopenharmony_ci}
14177db96d56Sopenharmony_ci
14187db96d56Sopenharmony_ci/*[clinic input]
14197db96d56Sopenharmony_ci_overlapped.Overlapped.ConnectEx
14207db96d56Sopenharmony_ci
14217db96d56Sopenharmony_ci    client_handle as ConnectSocket: HANDLE
14227db96d56Sopenharmony_ci    address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
14237db96d56Sopenharmony_ci    /
14247db96d56Sopenharmony_ci
14257db96d56Sopenharmony_ciStart overlapped connect.
14267db96d56Sopenharmony_ci
14277db96d56Sopenharmony_ciclient_handle should be unbound.
14287db96d56Sopenharmony_ci[clinic start generated code]*/
14297db96d56Sopenharmony_ci
14307db96d56Sopenharmony_cistatic PyObject *
14317db96d56Sopenharmony_ci_overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self,
14327db96d56Sopenharmony_ci                                      HANDLE ConnectSocket,
14337db96d56Sopenharmony_ci                                      PyObject *AddressObj)
14347db96d56Sopenharmony_ci/*[clinic end generated code: output=5aebbbdb4f022833 input=d6bbd2d84b156fc1]*/
14357db96d56Sopenharmony_ci{
14367db96d56Sopenharmony_ci    char AddressBuf[sizeof(struct sockaddr_in6)];
14377db96d56Sopenharmony_ci    SOCKADDR *Address = (SOCKADDR*)AddressBuf;
14387db96d56Sopenharmony_ci    int Length;
14397db96d56Sopenharmony_ci    BOOL ret;
14407db96d56Sopenharmony_ci    DWORD err;
14417db96d56Sopenharmony_ci
14427db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
14437db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
14447db96d56Sopenharmony_ci        return NULL;
14457db96d56Sopenharmony_ci    }
14467db96d56Sopenharmony_ci
14477db96d56Sopenharmony_ci    Length = sizeof(AddressBuf);
14487db96d56Sopenharmony_ci    Length = parse_address(AddressObj, Address, Length);
14497db96d56Sopenharmony_ci    if (Length < 0)
14507db96d56Sopenharmony_ci        return NULL;
14517db96d56Sopenharmony_ci
14527db96d56Sopenharmony_ci    self->type = TYPE_CONNECT;
14537db96d56Sopenharmony_ci    self->handle = ConnectSocket;
14547db96d56Sopenharmony_ci
14557db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
14567db96d56Sopenharmony_ci    ret = Py_ConnectEx((SOCKET)ConnectSocket, Address, Length,
14577db96d56Sopenharmony_ci                       NULL, 0, NULL, &self->overlapped);
14587db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
14597db96d56Sopenharmony_ci
14607db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
14617db96d56Sopenharmony_ci    switch (err) {
14627db96d56Sopenharmony_ci        case ERROR_SUCCESS:
14637db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
14647db96d56Sopenharmony_ci            Py_RETURN_NONE;
14657db96d56Sopenharmony_ci        default:
14667db96d56Sopenharmony_ci            Overlapped_clear(self);
14677db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
14687db96d56Sopenharmony_ci    }
14697db96d56Sopenharmony_ci}
14707db96d56Sopenharmony_ci
14717db96d56Sopenharmony_ci/*[clinic input]
14727db96d56Sopenharmony_ci_overlapped.Overlapped.DisconnectEx
14737db96d56Sopenharmony_ci
14747db96d56Sopenharmony_ci    handle as Socket: HANDLE
14757db96d56Sopenharmony_ci    flags: DWORD
14767db96d56Sopenharmony_ci    /
14777db96d56Sopenharmony_ci
14787db96d56Sopenharmony_ci[clinic start generated code]*/
14797db96d56Sopenharmony_ci
14807db96d56Sopenharmony_cistatic PyObject *
14817db96d56Sopenharmony_ci_overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self,
14827db96d56Sopenharmony_ci                                         HANDLE Socket, DWORD flags)
14837db96d56Sopenharmony_ci/*[clinic end generated code: output=8d64ddb8c93c2126 input=680845cdcdf820eb]*/
14847db96d56Sopenharmony_ci{
14857db96d56Sopenharmony_ci    BOOL ret;
14867db96d56Sopenharmony_ci    DWORD err;
14877db96d56Sopenharmony_ci
14887db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
14897db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
14907db96d56Sopenharmony_ci        return NULL;
14917db96d56Sopenharmony_ci    }
14927db96d56Sopenharmony_ci
14937db96d56Sopenharmony_ci    self->type = TYPE_DISCONNECT;
14947db96d56Sopenharmony_ci    self->handle = Socket;
14957db96d56Sopenharmony_ci
14967db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
14977db96d56Sopenharmony_ci    ret = Py_DisconnectEx((SOCKET)Socket, &self->overlapped, flags, 0);
14987db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
14997db96d56Sopenharmony_ci
15007db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
15017db96d56Sopenharmony_ci    switch (err) {
15027db96d56Sopenharmony_ci        case ERROR_SUCCESS:
15037db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
15047db96d56Sopenharmony_ci            Py_RETURN_NONE;
15057db96d56Sopenharmony_ci        default:
15067db96d56Sopenharmony_ci            Overlapped_clear(self);
15077db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
15087db96d56Sopenharmony_ci    }
15097db96d56Sopenharmony_ci}
15107db96d56Sopenharmony_ci
15117db96d56Sopenharmony_ci/*[clinic input]
15127db96d56Sopenharmony_ci_overlapped.Overlapped.TransmitFile
15137db96d56Sopenharmony_ci
15147db96d56Sopenharmony_ci    socket as Socket: HANDLE
15157db96d56Sopenharmony_ci    file as File: HANDLE
15167db96d56Sopenharmony_ci    offset: DWORD
15177db96d56Sopenharmony_ci    offset_high: DWORD
15187db96d56Sopenharmony_ci    count_to_write: DWORD
15197db96d56Sopenharmony_ci    count_per_send: DWORD
15207db96d56Sopenharmony_ci    flags: DWORD
15217db96d56Sopenharmony_ci    /
15227db96d56Sopenharmony_ci
15237db96d56Sopenharmony_ciTransmit file data over a connected socket.
15247db96d56Sopenharmony_ci[clinic start generated code]*/
15257db96d56Sopenharmony_ci
15267db96d56Sopenharmony_cistatic PyObject *
15277db96d56Sopenharmony_ci_overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self,
15287db96d56Sopenharmony_ci                                         HANDLE Socket, HANDLE File,
15297db96d56Sopenharmony_ci                                         DWORD offset, DWORD offset_high,
15307db96d56Sopenharmony_ci                                         DWORD count_to_write,
15317db96d56Sopenharmony_ci                                         DWORD count_per_send, DWORD flags)
15327db96d56Sopenharmony_ci/*[clinic end generated code: output=03f3ca5512e678fd input=7e6f97b391f60e8c]*/
15337db96d56Sopenharmony_ci{
15347db96d56Sopenharmony_ci    BOOL ret;
15357db96d56Sopenharmony_ci    DWORD err;
15367db96d56Sopenharmony_ci
15377db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
15387db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
15397db96d56Sopenharmony_ci        return NULL;
15407db96d56Sopenharmony_ci    }
15417db96d56Sopenharmony_ci
15427db96d56Sopenharmony_ci    self->type = TYPE_TRANSMIT_FILE;
15437db96d56Sopenharmony_ci    self->handle = Socket;
15447db96d56Sopenharmony_ci    self->overlapped.Offset = offset;
15457db96d56Sopenharmony_ci    self->overlapped.OffsetHigh = offset_high;
15467db96d56Sopenharmony_ci
15477db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
15487db96d56Sopenharmony_ci    ret = Py_TransmitFile((SOCKET)Socket, File, count_to_write,
15497db96d56Sopenharmony_ci                          count_per_send, &self->overlapped, NULL, flags);
15507db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
15517db96d56Sopenharmony_ci
15527db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
15537db96d56Sopenharmony_ci    switch (err) {
15547db96d56Sopenharmony_ci        case ERROR_SUCCESS:
15557db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
15567db96d56Sopenharmony_ci            Py_RETURN_NONE;
15577db96d56Sopenharmony_ci        default:
15587db96d56Sopenharmony_ci            Overlapped_clear(self);
15597db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
15607db96d56Sopenharmony_ci    }
15617db96d56Sopenharmony_ci}
15627db96d56Sopenharmony_ci
15637db96d56Sopenharmony_ci/*[clinic input]
15647db96d56Sopenharmony_ci_overlapped.Overlapped.ConnectNamedPipe
15657db96d56Sopenharmony_ci
15667db96d56Sopenharmony_ci    handle as Pipe: HANDLE
15677db96d56Sopenharmony_ci    /
15687db96d56Sopenharmony_ci
15697db96d56Sopenharmony_ciStart overlapped wait for a client to connect.
15707db96d56Sopenharmony_ci[clinic start generated code]*/
15717db96d56Sopenharmony_ci
15727db96d56Sopenharmony_cistatic PyObject *
15737db96d56Sopenharmony_ci_overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self,
15747db96d56Sopenharmony_ci                                             HANDLE Pipe)
15757db96d56Sopenharmony_ci/*[clinic end generated code: output=3e69adfe55818abe input=8b0d4cef8a72f7bc]*/
15767db96d56Sopenharmony_ci{
15777db96d56Sopenharmony_ci    BOOL ret;
15787db96d56Sopenharmony_ci    DWORD err;
15797db96d56Sopenharmony_ci
15807db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
15817db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
15827db96d56Sopenharmony_ci        return NULL;
15837db96d56Sopenharmony_ci    }
15847db96d56Sopenharmony_ci
15857db96d56Sopenharmony_ci    self->type = TYPE_CONNECT_NAMED_PIPE;
15867db96d56Sopenharmony_ci    self->handle = Pipe;
15877db96d56Sopenharmony_ci
15887db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
15897db96d56Sopenharmony_ci    ret = ConnectNamedPipe(Pipe, &self->overlapped);
15907db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
15917db96d56Sopenharmony_ci
15927db96d56Sopenharmony_ci    self->error = err = ret ? ERROR_SUCCESS : GetLastError();
15937db96d56Sopenharmony_ci    switch (err) {
15947db96d56Sopenharmony_ci        case ERROR_PIPE_CONNECTED:
15957db96d56Sopenharmony_ci            mark_as_completed(&self->overlapped);
15967db96d56Sopenharmony_ci            Py_RETURN_TRUE;
15977db96d56Sopenharmony_ci        case ERROR_SUCCESS:
15987db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
15997db96d56Sopenharmony_ci            Py_RETURN_FALSE;
16007db96d56Sopenharmony_ci        default:
16017db96d56Sopenharmony_ci            Overlapped_clear(self);
16027db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
16037db96d56Sopenharmony_ci    }
16047db96d56Sopenharmony_ci}
16057db96d56Sopenharmony_ci
16067db96d56Sopenharmony_ci/*[clinic input]
16077db96d56Sopenharmony_ci_overlapped.Overlapped.ConnectPipe
16087db96d56Sopenharmony_ci
16097db96d56Sopenharmony_ci    addr as Address: Py_UNICODE
16107db96d56Sopenharmony_ci    /
16117db96d56Sopenharmony_ci
16127db96d56Sopenharmony_ciConnect to the pipe for asynchronous I/O (overlapped).
16137db96d56Sopenharmony_ci[clinic start generated code]*/
16147db96d56Sopenharmony_ci
16157db96d56Sopenharmony_cistatic PyObject *
16167db96d56Sopenharmony_ci_overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self,
16177db96d56Sopenharmony_ci                                        const Py_UNICODE *Address)
16187db96d56Sopenharmony_ci/*[clinic end generated code: output=3cc9661667d459d4 input=167c06a274efcefc]*/
16197db96d56Sopenharmony_ci{
16207db96d56Sopenharmony_ci    HANDLE PipeHandle;
16217db96d56Sopenharmony_ci
16227db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
16237db96d56Sopenharmony_ci    PipeHandle = CreateFileW(Address,
16247db96d56Sopenharmony_ci                             GENERIC_READ | GENERIC_WRITE,
16257db96d56Sopenharmony_ci                             0, NULL, OPEN_EXISTING,
16267db96d56Sopenharmony_ci                             FILE_FLAG_OVERLAPPED, NULL);
16277db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
16287db96d56Sopenharmony_ci
16297db96d56Sopenharmony_ci    if (PipeHandle == INVALID_HANDLE_VALUE)
16307db96d56Sopenharmony_ci        return SetFromWindowsErr(0);
16317db96d56Sopenharmony_ci    return Py_BuildValue(F_HANDLE, PipeHandle);
16327db96d56Sopenharmony_ci}
16337db96d56Sopenharmony_ci
16347db96d56Sopenharmony_cistatic PyObject*
16357db96d56Sopenharmony_ciOverlapped_getaddress(OverlappedObject *self)
16367db96d56Sopenharmony_ci{
16377db96d56Sopenharmony_ci    return PyLong_FromVoidPtr(&self->overlapped);
16387db96d56Sopenharmony_ci}
16397db96d56Sopenharmony_ci
16407db96d56Sopenharmony_cistatic PyObject*
16417db96d56Sopenharmony_ciOverlapped_getpending(OverlappedObject *self)
16427db96d56Sopenharmony_ci{
16437db96d56Sopenharmony_ci    return PyBool_FromLong(!HasOverlappedIoCompleted(&self->overlapped) &&
16447db96d56Sopenharmony_ci                           self->type != TYPE_NOT_STARTED);
16457db96d56Sopenharmony_ci}
16467db96d56Sopenharmony_ci
16477db96d56Sopenharmony_cistatic int
16487db96d56Sopenharmony_ciOverlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
16497db96d56Sopenharmony_ci{
16507db96d56Sopenharmony_ci    switch (self->type) {
16517db96d56Sopenharmony_ci    case TYPE_READ:
16527db96d56Sopenharmony_ci    case TYPE_ACCEPT:
16537db96d56Sopenharmony_ci        Py_VISIT(self->allocated_buffer);
16547db96d56Sopenharmony_ci        break;
16557db96d56Sopenharmony_ci    case TYPE_WRITE:
16567db96d56Sopenharmony_ci    case TYPE_WRITE_TO:
16577db96d56Sopenharmony_ci    case TYPE_READINTO:
16587db96d56Sopenharmony_ci        if (self->user_buffer.obj) {
16597db96d56Sopenharmony_ci            Py_VISIT(&self->user_buffer.obj);
16607db96d56Sopenharmony_ci        }
16617db96d56Sopenharmony_ci        break;
16627db96d56Sopenharmony_ci    case TYPE_READ_FROM:
16637db96d56Sopenharmony_ci        Py_VISIT(self->read_from.result);
16647db96d56Sopenharmony_ci        Py_VISIT(self->read_from.allocated_buffer);
16657db96d56Sopenharmony_ci        break;
16667db96d56Sopenharmony_ci    case TYPE_READ_FROM_INTO:
16677db96d56Sopenharmony_ci        Py_VISIT(self->read_from_into.result);
16687db96d56Sopenharmony_ci        if (self->read_from_into.user_buffer.obj) {
16697db96d56Sopenharmony_ci            Py_VISIT(&self->read_from_into.user_buffer.obj);
16707db96d56Sopenharmony_ci        }
16717db96d56Sopenharmony_ci        break;
16727db96d56Sopenharmony_ci    }
16737db96d56Sopenharmony_ci    return 0;
16747db96d56Sopenharmony_ci}
16757db96d56Sopenharmony_ci
16767db96d56Sopenharmony_ci// UDP functions
16777db96d56Sopenharmony_ci
16787db96d56Sopenharmony_ci/*
16797db96d56Sopenharmony_ci * Note: WSAConnect does not support Overlapped I/O so this function should
16807db96d56Sopenharmony_ci * _only_ be used for connectionless sockets (UDP).
16817db96d56Sopenharmony_ci */
16827db96d56Sopenharmony_ci
16837db96d56Sopenharmony_ci/*[clinic input]
16847db96d56Sopenharmony_ci_overlapped.WSAConnect
16857db96d56Sopenharmony_ci
16867db96d56Sopenharmony_ci    client_handle as ConnectSocket: HANDLE
16877db96d56Sopenharmony_ci    address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
16887db96d56Sopenharmony_ci    /
16897db96d56Sopenharmony_ci
16907db96d56Sopenharmony_ciBind a remote address to a connectionless (UDP) socket.
16917db96d56Sopenharmony_ci[clinic start generated code]*/
16927db96d56Sopenharmony_ci
16937db96d56Sopenharmony_cistatic PyObject *
16947db96d56Sopenharmony_ci_overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket,
16957db96d56Sopenharmony_ci                            PyObject *AddressObj)
16967db96d56Sopenharmony_ci/*[clinic end generated code: output=ea0b4391e94dad63 input=7cf65313d49c015a]*/
16977db96d56Sopenharmony_ci{
16987db96d56Sopenharmony_ci    char AddressBuf[sizeof(struct sockaddr_in6)];
16997db96d56Sopenharmony_ci    SOCKADDR *Address = (SOCKADDR*)AddressBuf;
17007db96d56Sopenharmony_ci    int Length;
17017db96d56Sopenharmony_ci    int err;
17027db96d56Sopenharmony_ci
17037db96d56Sopenharmony_ci    Length = sizeof(AddressBuf);
17047db96d56Sopenharmony_ci    Length = parse_address(AddressObj, Address, Length);
17057db96d56Sopenharmony_ci    if (Length < 0) {
17067db96d56Sopenharmony_ci        return NULL;
17077db96d56Sopenharmony_ci    }
17087db96d56Sopenharmony_ci
17097db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
17107db96d56Sopenharmony_ci    // WSAConnect does not support overlapped I/O so this call will
17117db96d56Sopenharmony_ci    // successfully complete immediately.
17127db96d56Sopenharmony_ci    err = WSAConnect((SOCKET)ConnectSocket, Address, Length,
17137db96d56Sopenharmony_ci                        NULL, NULL, NULL, NULL);
17147db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
17157db96d56Sopenharmony_ci
17167db96d56Sopenharmony_ci    if (err == 0) {
17177db96d56Sopenharmony_ci        Py_RETURN_NONE;
17187db96d56Sopenharmony_ci    }
17197db96d56Sopenharmony_ci    else {
17207db96d56Sopenharmony_ci        return SetFromWindowsErr(WSAGetLastError());
17217db96d56Sopenharmony_ci    }
17227db96d56Sopenharmony_ci}
17237db96d56Sopenharmony_ci
17247db96d56Sopenharmony_ci/*[clinic input]
17257db96d56Sopenharmony_ci_overlapped.Overlapped.WSASendTo
17267db96d56Sopenharmony_ci
17277db96d56Sopenharmony_ci    handle: HANDLE
17287db96d56Sopenharmony_ci    buf as bufobj: Py_buffer
17297db96d56Sopenharmony_ci    flags: DWORD
17307db96d56Sopenharmony_ci    address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
17317db96d56Sopenharmony_ci    /
17327db96d56Sopenharmony_ci
17337db96d56Sopenharmony_ciStart overlapped sendto over a connectionless (UDP) socket.
17347db96d56Sopenharmony_ci[clinic start generated code]*/
17357db96d56Sopenharmony_ci
17367db96d56Sopenharmony_cistatic PyObject *
17377db96d56Sopenharmony_ci_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
17387db96d56Sopenharmony_ci                                      Py_buffer *bufobj, DWORD flags,
17397db96d56Sopenharmony_ci                                      PyObject *AddressObj)
17407db96d56Sopenharmony_ci/*[clinic end generated code: output=3cdedc4cfaeb70cd input=31f44cd4ab92fc33]*/
17417db96d56Sopenharmony_ci{
17427db96d56Sopenharmony_ci    char AddressBuf[sizeof(struct sockaddr_in6)];
17437db96d56Sopenharmony_ci    SOCKADDR *Address = (SOCKADDR*)AddressBuf;
17447db96d56Sopenharmony_ci    int AddressLength;
17457db96d56Sopenharmony_ci    DWORD written;
17467db96d56Sopenharmony_ci    WSABUF wsabuf;
17477db96d56Sopenharmony_ci    int ret;
17487db96d56Sopenharmony_ci    DWORD err;
17497db96d56Sopenharmony_ci
17507db96d56Sopenharmony_ci    // Parse the "to" address
17517db96d56Sopenharmony_ci    AddressLength = sizeof(AddressBuf);
17527db96d56Sopenharmony_ci    AddressLength = parse_address(AddressObj, Address, AddressLength);
17537db96d56Sopenharmony_ci    if (AddressLength < 0) {
17547db96d56Sopenharmony_ci        return NULL;
17557db96d56Sopenharmony_ci    }
17567db96d56Sopenharmony_ci
17577db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
17587db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
17597db96d56Sopenharmony_ci        return NULL;
17607db96d56Sopenharmony_ci    }
17617db96d56Sopenharmony_ci
17627db96d56Sopenharmony_ci#if SIZEOF_SIZE_T > SIZEOF_LONG
17637db96d56Sopenharmony_ci    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
17647db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "buffer too large");
17657db96d56Sopenharmony_ci        return NULL;
17667db96d56Sopenharmony_ci    }
17677db96d56Sopenharmony_ci#endif
17687db96d56Sopenharmony_ci    steal_buffer(&self->user_buffer, bufobj);
17697db96d56Sopenharmony_ci
17707db96d56Sopenharmony_ci    self->type = TYPE_WRITE_TO;
17717db96d56Sopenharmony_ci    self->handle = handle;
17727db96d56Sopenharmony_ci    wsabuf.len = (DWORD)self->user_buffer.len;
17737db96d56Sopenharmony_ci    wsabuf.buf = self->user_buffer.buf;
17747db96d56Sopenharmony_ci
17757db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
17767db96d56Sopenharmony_ci    ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags,
17777db96d56Sopenharmony_ci                    Address, AddressLength, &self->overlapped, NULL);
17787db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
17797db96d56Sopenharmony_ci
17807db96d56Sopenharmony_ci    self->error = err = (ret == SOCKET_ERROR ? WSAGetLastError() :
17817db96d56Sopenharmony_ci                                               ERROR_SUCCESS);
17827db96d56Sopenharmony_ci
17837db96d56Sopenharmony_ci    switch(err) {
17847db96d56Sopenharmony_ci        case ERROR_SUCCESS:
17857db96d56Sopenharmony_ci        case ERROR_IO_PENDING:
17867db96d56Sopenharmony_ci            Py_RETURN_NONE;
17877db96d56Sopenharmony_ci        default:
17887db96d56Sopenharmony_ci            self->type = TYPE_NOT_STARTED;
17897db96d56Sopenharmony_ci            return SetFromWindowsErr(err);
17907db96d56Sopenharmony_ci    }
17917db96d56Sopenharmony_ci}
17927db96d56Sopenharmony_ci
17937db96d56Sopenharmony_ci
17947db96d56Sopenharmony_ci
17957db96d56Sopenharmony_ciPyDoc_STRVAR(
17967db96d56Sopenharmony_ci    Overlapped_WSARecvFrom_doc,
17977db96d56Sopenharmony_ci    "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n"
17987db96d56Sopenharmony_ci    "Start overlapped receive");
17997db96d56Sopenharmony_ci
18007db96d56Sopenharmony_ci/*[clinic input]
18017db96d56Sopenharmony_ci_overlapped.Overlapped.WSARecvFrom
18027db96d56Sopenharmony_ci
18037db96d56Sopenharmony_ci    handle: HANDLE
18047db96d56Sopenharmony_ci    size: DWORD
18057db96d56Sopenharmony_ci    flags: DWORD = 0
18067db96d56Sopenharmony_ci    /
18077db96d56Sopenharmony_ci
18087db96d56Sopenharmony_ciStart overlapped receive.
18097db96d56Sopenharmony_ci[clinic start generated code]*/
18107db96d56Sopenharmony_ci
18117db96d56Sopenharmony_cistatic PyObject *
18127db96d56Sopenharmony_ci_overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self,
18137db96d56Sopenharmony_ci                                        HANDLE handle, DWORD size,
18147db96d56Sopenharmony_ci                                        DWORD flags)
18157db96d56Sopenharmony_ci/*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/
18167db96d56Sopenharmony_ci{
18177db96d56Sopenharmony_ci    PyObject *buf;
18187db96d56Sopenharmony_ci    DWORD nread;
18197db96d56Sopenharmony_ci    WSABUF wsabuf;
18207db96d56Sopenharmony_ci    int ret;
18217db96d56Sopenharmony_ci    DWORD err;
18227db96d56Sopenharmony_ci
18237db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
18247db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
18257db96d56Sopenharmony_ci        return NULL;
18267db96d56Sopenharmony_ci    }
18277db96d56Sopenharmony_ci
18287db96d56Sopenharmony_ci#if SIZEOF_SIZE_T <= SIZEOF_LONG
18297db96d56Sopenharmony_ci    size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
18307db96d56Sopenharmony_ci#endif
18317db96d56Sopenharmony_ci    buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
18327db96d56Sopenharmony_ci    if (buf == NULL) {
18337db96d56Sopenharmony_ci        return NULL;
18347db96d56Sopenharmony_ci    }
18357db96d56Sopenharmony_ci
18367db96d56Sopenharmony_ci    wsabuf.buf = PyBytes_AS_STRING(buf);
18377db96d56Sopenharmony_ci    wsabuf.len = size;
18387db96d56Sopenharmony_ci
18397db96d56Sopenharmony_ci    self->type = TYPE_READ_FROM;
18407db96d56Sopenharmony_ci    self->handle = handle;
18417db96d56Sopenharmony_ci    self->read_from.allocated_buffer = buf;
18427db96d56Sopenharmony_ci    memset(&self->read_from.address, 0, sizeof(self->read_from.address));
18437db96d56Sopenharmony_ci    self->read_from.address_length = sizeof(self->read_from.address);
18447db96d56Sopenharmony_ci
18457db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
18467db96d56Sopenharmony_ci    ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
18477db96d56Sopenharmony_ci                      (SOCKADDR*)&self->read_from.address,
18487db96d56Sopenharmony_ci                      &self->read_from.address_length,
18497db96d56Sopenharmony_ci                      &self->overlapped, NULL);
18507db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
18517db96d56Sopenharmony_ci
18527db96d56Sopenharmony_ci    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
18537db96d56Sopenharmony_ci    switch (err) {
18547db96d56Sopenharmony_ci    case ERROR_BROKEN_PIPE:
18557db96d56Sopenharmony_ci        mark_as_completed(&self->overlapped);
18567db96d56Sopenharmony_ci        return SetFromWindowsErr(err);
18577db96d56Sopenharmony_ci    case ERROR_SUCCESS:
18587db96d56Sopenharmony_ci    case ERROR_MORE_DATA:
18597db96d56Sopenharmony_ci    case ERROR_IO_PENDING:
18607db96d56Sopenharmony_ci        Py_RETURN_NONE;
18617db96d56Sopenharmony_ci    default:
18627db96d56Sopenharmony_ci        self->type = TYPE_NOT_STARTED;
18637db96d56Sopenharmony_ci        return SetFromWindowsErr(err);
18647db96d56Sopenharmony_ci    }
18657db96d56Sopenharmony_ci}
18667db96d56Sopenharmony_ci
18677db96d56Sopenharmony_ci
18687db96d56Sopenharmony_ci/*[clinic input]
18697db96d56Sopenharmony_ci_overlapped.Overlapped.WSARecvFromInto
18707db96d56Sopenharmony_ci
18717db96d56Sopenharmony_ci    handle: HANDLE
18727db96d56Sopenharmony_ci    buf as bufobj: Py_buffer
18737db96d56Sopenharmony_ci    size: DWORD
18747db96d56Sopenharmony_ci    flags: DWORD = 0
18757db96d56Sopenharmony_ci    /
18767db96d56Sopenharmony_ci
18777db96d56Sopenharmony_ciStart overlapped receive.
18787db96d56Sopenharmony_ci[clinic start generated code]*/
18797db96d56Sopenharmony_ci
18807db96d56Sopenharmony_cistatic PyObject *
18817db96d56Sopenharmony_ci_overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self,
18827db96d56Sopenharmony_ci                                            HANDLE handle, Py_buffer *bufobj,
18837db96d56Sopenharmony_ci                                            DWORD size, DWORD flags)
18847db96d56Sopenharmony_ci/*[clinic end generated code: output=30c7ea171a691757 input=4be4b08d03531e76]*/
18857db96d56Sopenharmony_ci{
18867db96d56Sopenharmony_ci    DWORD nread;
18877db96d56Sopenharmony_ci    WSABUF wsabuf;
18887db96d56Sopenharmony_ci    int ret;
18897db96d56Sopenharmony_ci    DWORD err;
18907db96d56Sopenharmony_ci
18917db96d56Sopenharmony_ci    if (self->type != TYPE_NONE) {
18927db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "operation already attempted");
18937db96d56Sopenharmony_ci        return NULL;
18947db96d56Sopenharmony_ci    }
18957db96d56Sopenharmony_ci
18967db96d56Sopenharmony_ci#if SIZEOF_SIZE_T > SIZEOF_LONG
18977db96d56Sopenharmony_ci    if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
18987db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "buffer too large");
18997db96d56Sopenharmony_ci        return NULL;
19007db96d56Sopenharmony_ci    }
19017db96d56Sopenharmony_ci#endif
19027db96d56Sopenharmony_ci
19037db96d56Sopenharmony_ci    wsabuf.buf = bufobj->buf;
19047db96d56Sopenharmony_ci    wsabuf.len = size;
19057db96d56Sopenharmony_ci
19067db96d56Sopenharmony_ci    self->type = TYPE_READ_FROM_INTO;
19077db96d56Sopenharmony_ci    self->handle = handle;
19087db96d56Sopenharmony_ci    steal_buffer(&self->read_from_into.user_buffer, bufobj);
19097db96d56Sopenharmony_ci    memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address));
19107db96d56Sopenharmony_ci    self->read_from_into.address_length = sizeof(self->read_from_into.address);
19117db96d56Sopenharmony_ci
19127db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
19137db96d56Sopenharmony_ci    ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
19147db96d56Sopenharmony_ci                      (SOCKADDR*)&self->read_from_into.address,
19157db96d56Sopenharmony_ci                      &self->read_from_into.address_length,
19167db96d56Sopenharmony_ci                      &self->overlapped, NULL);
19177db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
19187db96d56Sopenharmony_ci
19197db96d56Sopenharmony_ci    self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
19207db96d56Sopenharmony_ci    switch (err) {
19217db96d56Sopenharmony_ci    case ERROR_BROKEN_PIPE:
19227db96d56Sopenharmony_ci        mark_as_completed(&self->overlapped);
19237db96d56Sopenharmony_ci        return SetFromWindowsErr(err);
19247db96d56Sopenharmony_ci    case ERROR_SUCCESS:
19257db96d56Sopenharmony_ci    case ERROR_MORE_DATA:
19267db96d56Sopenharmony_ci    case ERROR_IO_PENDING:
19277db96d56Sopenharmony_ci        Py_RETURN_NONE;
19287db96d56Sopenharmony_ci    default:
19297db96d56Sopenharmony_ci        self->type = TYPE_NOT_STARTED;
19307db96d56Sopenharmony_ci        return SetFromWindowsErr(err);
19317db96d56Sopenharmony_ci    }
19327db96d56Sopenharmony_ci}
19337db96d56Sopenharmony_ci
19347db96d56Sopenharmony_ci
19357db96d56Sopenharmony_ci#include "clinic/overlapped.c.h"
19367db96d56Sopenharmony_ci
19377db96d56Sopenharmony_cistatic PyMethodDef Overlapped_methods[] = {
19387db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF
19397db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF
19407db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF
19417db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF
19427db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF
19437db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF
19447db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
19457db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF
19467db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF
19477db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF
19487db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF
19497db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF
19507db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF
19517db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF
19527db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF
19537db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
19547db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF
19557db96d56Sopenharmony_ci    {NULL}
19567db96d56Sopenharmony_ci};
19577db96d56Sopenharmony_ci
19587db96d56Sopenharmony_cistatic PyMemberDef Overlapped_members[] = {
19597db96d56Sopenharmony_ci    {"error", T_ULONG,
19607db96d56Sopenharmony_ci     offsetof(OverlappedObject, error),
19617db96d56Sopenharmony_ci     READONLY, "Error from last operation"},
19627db96d56Sopenharmony_ci    {"event", T_HANDLE,
19637db96d56Sopenharmony_ci     offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
19647db96d56Sopenharmony_ci     READONLY, "Overlapped event handle"},
19657db96d56Sopenharmony_ci    {NULL}
19667db96d56Sopenharmony_ci};
19677db96d56Sopenharmony_ci
19687db96d56Sopenharmony_cistatic PyGetSetDef Overlapped_getsets[] = {
19697db96d56Sopenharmony_ci    {"address", (getter)Overlapped_getaddress, NULL,
19707db96d56Sopenharmony_ci     "Address of overlapped structure"},
19717db96d56Sopenharmony_ci    {"pending", (getter)Overlapped_getpending, NULL,
19727db96d56Sopenharmony_ci     "Whether the operation is pending"},
19737db96d56Sopenharmony_ci    {NULL},
19747db96d56Sopenharmony_ci};
19757db96d56Sopenharmony_ci
19767db96d56Sopenharmony_cistatic PyType_Slot overlapped_type_slots[] = {
19777db96d56Sopenharmony_ci    {Py_tp_dealloc, Overlapped_dealloc},
19787db96d56Sopenharmony_ci    {Py_tp_doc, (char *)_overlapped_Overlapped__doc__},
19797db96d56Sopenharmony_ci    {Py_tp_traverse, Overlapped_traverse},
19807db96d56Sopenharmony_ci    {Py_tp_methods, Overlapped_methods},
19817db96d56Sopenharmony_ci    {Py_tp_members, Overlapped_members},
19827db96d56Sopenharmony_ci    {Py_tp_getset, Overlapped_getsets},
19837db96d56Sopenharmony_ci    {Py_tp_new, _overlapped_Overlapped},
19847db96d56Sopenharmony_ci    {0,0}
19857db96d56Sopenharmony_ci};
19867db96d56Sopenharmony_ci
19877db96d56Sopenharmony_cistatic PyType_Spec overlapped_type_spec = {
19887db96d56Sopenharmony_ci    .name = "_overlapped.Overlapped",
19897db96d56Sopenharmony_ci    .basicsize = sizeof(OverlappedObject),
19907db96d56Sopenharmony_ci    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
19917db96d56Sopenharmony_ci    .slots = overlapped_type_slots
19927db96d56Sopenharmony_ci};
19937db96d56Sopenharmony_ci
19947db96d56Sopenharmony_cistatic PyMethodDef overlapped_functions[] = {
19957db96d56Sopenharmony_ci    _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF
19967db96d56Sopenharmony_ci    _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF
19977db96d56Sopenharmony_ci    _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF
19987db96d56Sopenharmony_ci    _OVERLAPPED_FORMATMESSAGE_METHODDEF
19997db96d56Sopenharmony_ci    _OVERLAPPED_BINDLOCAL_METHODDEF
20007db96d56Sopenharmony_ci    _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF
20017db96d56Sopenharmony_ci    _OVERLAPPED_UNREGISTERWAIT_METHODDEF
20027db96d56Sopenharmony_ci    _OVERLAPPED_UNREGISTERWAITEX_METHODDEF
20037db96d56Sopenharmony_ci    _OVERLAPPED_CREATEEVENT_METHODDEF
20047db96d56Sopenharmony_ci    _OVERLAPPED_SETEVENT_METHODDEF
20057db96d56Sopenharmony_ci    _OVERLAPPED_RESETEVENT_METHODDEF
20067db96d56Sopenharmony_ci    _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF
20077db96d56Sopenharmony_ci    _OVERLAPPED_WSACONNECT_METHODDEF
20087db96d56Sopenharmony_ci    {NULL}
20097db96d56Sopenharmony_ci};
20107db96d56Sopenharmony_ci
20117db96d56Sopenharmony_cistatic int
20127db96d56Sopenharmony_cioverlapped_traverse(PyObject *module, visitproc visit, void *arg)
20137db96d56Sopenharmony_ci{
20147db96d56Sopenharmony_ci    OverlappedState *state = overlapped_get_state(module);
20157db96d56Sopenharmony_ci    Py_VISIT(state->overlapped_type);
20167db96d56Sopenharmony_ci    return 0;
20177db96d56Sopenharmony_ci}
20187db96d56Sopenharmony_ci
20197db96d56Sopenharmony_cistatic int
20207db96d56Sopenharmony_cioverlapped_clear(PyObject *module)
20217db96d56Sopenharmony_ci{
20227db96d56Sopenharmony_ci    OverlappedState *state = overlapped_get_state(module);
20237db96d56Sopenharmony_ci    Py_CLEAR(state->overlapped_type);
20247db96d56Sopenharmony_ci    return 0;
20257db96d56Sopenharmony_ci}
20267db96d56Sopenharmony_ci
20277db96d56Sopenharmony_cistatic void
20287db96d56Sopenharmony_cioverlapped_free(void *module)
20297db96d56Sopenharmony_ci{
20307db96d56Sopenharmony_ci    overlapped_clear((PyObject *)module);
20317db96d56Sopenharmony_ci}
20327db96d56Sopenharmony_ci
20337db96d56Sopenharmony_ci#define WINAPI_CONSTANT(fmt, con) \
20347db96d56Sopenharmony_ci    do { \
20357db96d56Sopenharmony_ci        PyObject *value = Py_BuildValue(fmt, con); \
20367db96d56Sopenharmony_ci        if (value == NULL) { \
20377db96d56Sopenharmony_ci            return -1; \
20387db96d56Sopenharmony_ci        } \
20397db96d56Sopenharmony_ci        if (PyModule_AddObject(module, #con, value) < 0 ) { \
20407db96d56Sopenharmony_ci            Py_DECREF(value); \
20417db96d56Sopenharmony_ci            return -1; \
20427db96d56Sopenharmony_ci        } \
20437db96d56Sopenharmony_ci    } while (0)
20447db96d56Sopenharmony_ci
20457db96d56Sopenharmony_cistatic int
20467db96d56Sopenharmony_cioverlapped_exec(PyObject *module)
20477db96d56Sopenharmony_ci{
20487db96d56Sopenharmony_ci    /* Ensure WSAStartup() called before initializing function pointers */
20497db96d56Sopenharmony_ci    PyObject *socket_module = PyImport_ImportModule("_socket");
20507db96d56Sopenharmony_ci    if (!socket_module) {
20517db96d56Sopenharmony_ci        return -1;
20527db96d56Sopenharmony_ci    }
20537db96d56Sopenharmony_ci
20547db96d56Sopenharmony_ci    Py_DECREF(socket_module);
20557db96d56Sopenharmony_ci
20567db96d56Sopenharmony_ci    if (initialize_function_pointers() < 0) {
20577db96d56Sopenharmony_ci        return -1;
20587db96d56Sopenharmony_ci    }
20597db96d56Sopenharmony_ci
20607db96d56Sopenharmony_ci    OverlappedState *st = overlapped_get_state(module);
20617db96d56Sopenharmony_ci    st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(
20627db96d56Sopenharmony_ci        module, &overlapped_type_spec, NULL);
20637db96d56Sopenharmony_ci    if (st->overlapped_type == NULL) {
20647db96d56Sopenharmony_ci        return -1;
20657db96d56Sopenharmony_ci    }
20667db96d56Sopenharmony_ci
20677db96d56Sopenharmony_ci    if (PyModule_AddType(module, st->overlapped_type) < 0) {
20687db96d56Sopenharmony_ci        return -1;
20697db96d56Sopenharmony_ci    }
20707db96d56Sopenharmony_ci
20717db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  ERROR_IO_PENDING);
20727db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  ERROR_NETNAME_DELETED);
20737db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  ERROR_OPERATION_ABORTED);
20747db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  ERROR_SEM_TIMEOUT);
20757db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  ERROR_PIPE_BUSY);
20767db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  INFINITE);
20777db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE);
20787db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_HANDLE, NULL);
20797db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  SO_UPDATE_ACCEPT_CONTEXT);
20807db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  SO_UPDATE_CONNECT_CONTEXT);
20817db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD,  TF_REUSE_SOCKET);
20827db96d56Sopenharmony_ci
20837db96d56Sopenharmony_ci    return 0;
20847db96d56Sopenharmony_ci}
20857db96d56Sopenharmony_ci
20867db96d56Sopenharmony_cistatic PyModuleDef_Slot overlapped_slots[] = {
20877db96d56Sopenharmony_ci    {Py_mod_exec, overlapped_exec},
20887db96d56Sopenharmony_ci    {0, NULL}
20897db96d56Sopenharmony_ci};
20907db96d56Sopenharmony_ci
20917db96d56Sopenharmony_cistatic struct PyModuleDef overlapped_module = {
20927db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
20937db96d56Sopenharmony_ci    .m_name = "_overlapped",
20947db96d56Sopenharmony_ci    .m_size = sizeof(OverlappedState),
20957db96d56Sopenharmony_ci    .m_methods = overlapped_functions,
20967db96d56Sopenharmony_ci    .m_slots = overlapped_slots,
20977db96d56Sopenharmony_ci    .m_traverse = overlapped_traverse,
20987db96d56Sopenharmony_ci    .m_clear = overlapped_clear,
20997db96d56Sopenharmony_ci    .m_free = overlapped_free
21007db96d56Sopenharmony_ci};
21017db96d56Sopenharmony_ci
21027db96d56Sopenharmony_ciPyMODINIT_FUNC
21037db96d56Sopenharmony_ciPyInit__overlapped(void)
21047db96d56Sopenharmony_ci{
21057db96d56Sopenharmony_ci    return PyModuleDef_Init(&overlapped_module);
21067db96d56Sopenharmony_ci}
2107