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