overlapped.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088
  1. /*
  2. * Support for overlapped IO
  3. *
  4. * Some code borrowed from Modules/_winapi.c of CPython
  5. */
  6. /* XXX check overflow and DWORD <-> Py_ssize_t conversions
  7. Check itemsize */
  8. #include "Python.h"
  9. #include "structmember.h" // PyMemberDef
  10. #define WINDOWS_LEAN_AND_MEAN
  11. #include <winsock2.h>
  12. #include <ws2tcpip.h>
  13. #include <mswsock.h>
  14. #if defined(MS_WIN32) && !defined(MS_WIN64)
  15. # define F_POINTER "k"
  16. # define T_POINTER T_ULONG
  17. #else
  18. # define F_POINTER "K"
  19. # define T_POINTER T_ULONGLONG
  20. #endif
  21. #define F_HANDLE F_POINTER
  22. #define F_ULONG_PTR F_POINTER
  23. #define F_DWORD "k"
  24. #define F_BOOL "i"
  25. #define F_UINT "I"
  26. #define T_HANDLE T_POINTER
  27. /*[python input]
  28. class pointer_converter(CConverter):
  29. format_unit = '"F_POINTER"'
  30. def parse_arg(self, argname, displayname):
  31. return """
  32. {paramname} = PyLong_AsVoidPtr({argname});
  33. if (!{paramname} && PyErr_Occurred()) {{{{
  34. goto exit;
  35. }}}}
  36. """.format(argname=argname, paramname=self.parser_name)
  37. class OVERLAPPED_converter(pointer_converter):
  38. type = 'OVERLAPPED *'
  39. class HANDLE_converter(pointer_converter):
  40. type = 'HANDLE'
  41. class ULONG_PTR_converter(pointer_converter):
  42. type = 'ULONG_PTR'
  43. def parse_arg(self, argname, displayname):
  44. return """
  45. {paramname} = (uintptr_t)PyLong_AsVoidPtr({argname});
  46. if (!{paramname} && PyErr_Occurred()) {{{{
  47. goto exit;
  48. }}}}
  49. """.format(argname=argname, paramname=self.parser_name)
  50. class DWORD_converter(unsigned_long_converter):
  51. type = 'DWORD'
  52. class BOOL_converter(int_converter):
  53. type = 'BOOL'
  54. [python start generated code]*/
  55. /*[python end generated code: output=da39a3ee5e6b4b0d input=8a07ea3018f4cec8]*/
  56. /*[clinic input]
  57. module _overlapped
  58. class _overlapped.Overlapped "OverlappedObject *" "&OverlappedType"
  59. [clinic start generated code]*/
  60. /*[clinic end generated code: output=da39a3ee5e6b4b0d input=92e5a799db35b96c]*/
  61. enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE,
  62. TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE,
  63. TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM,
  64. TYPE_WRITE_TO, TYPE_READ_FROM_INTO};
  65. typedef struct {
  66. PyObject_HEAD
  67. OVERLAPPED overlapped;
  68. /* For convenience, we store the file handle too */
  69. HANDLE handle;
  70. /* Error returned by last method call */
  71. DWORD error;
  72. /* Type of operation */
  73. DWORD type;
  74. union {
  75. /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */
  76. PyObject *allocated_buffer;
  77. /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */
  78. Py_buffer user_buffer;
  79. /* Data used for reading from a connectionless socket:
  80. TYPE_READ_FROM */
  81. struct {
  82. // A (buffer, (host, port)) tuple
  83. PyObject *result;
  84. // The actual read buffer
  85. PyObject *allocated_buffer;
  86. struct sockaddr_in6 address;
  87. int address_length;
  88. } read_from;
  89. /* Data used for reading from a connectionless socket:
  90. TYPE_READ_FROM_INTO */
  91. struct {
  92. // A (number of bytes read, (host, port)) tuple
  93. PyObject* result;
  94. /* Buffer passed by the user */
  95. Py_buffer user_buffer;
  96. struct sockaddr_in6 address;
  97. int address_length;
  98. } read_from_into;
  99. };
  100. } OverlappedObject;
  101. static inline void
  102. steal_buffer(Py_buffer * dst, Py_buffer * src)
  103. {
  104. memcpy(dst, src, sizeof(Py_buffer));
  105. memset(src, 0, sizeof(Py_buffer));
  106. }
  107. /*
  108. * Map Windows error codes to subclasses of OSError
  109. */
  110. static PyObject *
  111. SetFromWindowsErr(DWORD err)
  112. {
  113. PyObject *exception_type;
  114. if (err == 0)
  115. err = GetLastError();
  116. switch (err) {
  117. case ERROR_CONNECTION_REFUSED:
  118. exception_type = PyExc_ConnectionRefusedError;
  119. break;
  120. case ERROR_CONNECTION_ABORTED:
  121. exception_type = PyExc_ConnectionAbortedError;
  122. break;
  123. default:
  124. exception_type = PyExc_OSError;
  125. }
  126. return PyErr_SetExcFromWindowsErr(exception_type, err);
  127. }
  128. /*
  129. * Some functions should be loaded at runtime
  130. */
  131. static LPFN_ACCEPTEX Py_AcceptEx = NULL;
  132. static LPFN_CONNECTEX Py_ConnectEx = NULL;
  133. static LPFN_DISCONNECTEX Py_DisconnectEx = NULL;
  134. static LPFN_TRANSMITFILE Py_TransmitFile = NULL;
  135. #define GET_WSA_POINTER(s, x) \
  136. (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \
  137. &Guid##x, sizeof(Guid##x), &Py_##x, \
  138. sizeof(Py_##x), &dwBytes, NULL, NULL))
  139. static int
  140. initialize_function_pointers(void)
  141. {
  142. GUID GuidAcceptEx = WSAID_ACCEPTEX;
  143. GUID GuidConnectEx = WSAID_CONNECTEX;
  144. GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
  145. GUID GuidTransmitFile = WSAID_TRANSMITFILE;
  146. SOCKET s;
  147. DWORD dwBytes;
  148. if (Py_AcceptEx != NULL &&
  149. Py_ConnectEx != NULL &&
  150. Py_DisconnectEx != NULL &&
  151. Py_TransmitFile != NULL)
  152. {
  153. // All function pointers are initialized already
  154. // by previous module import
  155. return 0;
  156. }
  157. s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  158. if (s == INVALID_SOCKET) {
  159. SetFromWindowsErr(WSAGetLastError());
  160. return -1;
  161. }
  162. if (!GET_WSA_POINTER(s, AcceptEx) ||
  163. !GET_WSA_POINTER(s, ConnectEx) ||
  164. !GET_WSA_POINTER(s, DisconnectEx) ||
  165. !GET_WSA_POINTER(s, TransmitFile))
  166. {
  167. closesocket(s);
  168. SetFromWindowsErr(WSAGetLastError());
  169. return -1;
  170. }
  171. closesocket(s);
  172. return 0;
  173. }
  174. /*
  175. * Completion port stuff
  176. */
  177. /*[clinic input]
  178. _overlapped.CreateIoCompletionPort
  179. handle as FileHandle: HANDLE
  180. port as ExistingCompletionPort: HANDLE
  181. key as CompletionKey: ULONG_PTR
  182. concurrency as NumberOfConcurrentThreads: DWORD
  183. /
  184. Create a completion port or register a handle with a port.
  185. [clinic start generated code]*/
  186. static PyObject *
  187. _overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle,
  188. HANDLE ExistingCompletionPort,
  189. ULONG_PTR CompletionKey,
  190. DWORD NumberOfConcurrentThreads)
  191. /*[clinic end generated code: output=24ede2b0f05e5433 input=847bae4d0efe1976]*/
  192. {
  193. HANDLE ret;
  194. Py_BEGIN_ALLOW_THREADS
  195. ret = CreateIoCompletionPort(FileHandle, ExistingCompletionPort,
  196. CompletionKey, NumberOfConcurrentThreads);
  197. Py_END_ALLOW_THREADS
  198. if (ret == NULL)
  199. return SetFromWindowsErr(0);
  200. return Py_BuildValue(F_HANDLE, ret);
  201. }
  202. /*[clinic input]
  203. _overlapped.GetQueuedCompletionStatus
  204. port as CompletionPort: HANDLE
  205. msecs as Milliseconds: DWORD
  206. /
  207. Get a message from completion port.
  208. Wait for up to msecs milliseconds.
  209. [clinic start generated code]*/
  210. static PyObject *
  211. _overlapped_GetQueuedCompletionStatus_impl(PyObject *module,
  212. HANDLE CompletionPort,
  213. DWORD Milliseconds)
  214. /*[clinic end generated code: output=68314171628dddb7 input=94a042d14c4f6410]*/
  215. {
  216. DWORD NumberOfBytes = 0;
  217. ULONG_PTR CompletionKey = 0;
  218. OVERLAPPED *Overlapped = NULL;
  219. DWORD err;
  220. BOOL ret;
  221. Py_BEGIN_ALLOW_THREADS
  222. ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes,
  223. &CompletionKey, &Overlapped, Milliseconds);
  224. Py_END_ALLOW_THREADS
  225. err = ret ? ERROR_SUCCESS : GetLastError();
  226. if (Overlapped == NULL) {
  227. if (err == WAIT_TIMEOUT)
  228. Py_RETURN_NONE;
  229. else
  230. return SetFromWindowsErr(err);
  231. }
  232. return Py_BuildValue(F_DWORD F_DWORD F_ULONG_PTR F_POINTER,
  233. err, NumberOfBytes, CompletionKey, Overlapped);
  234. }
  235. /*[clinic input]
  236. _overlapped.PostQueuedCompletionStatus
  237. port as CompletionPort: HANDLE
  238. bytes as NumberOfBytes: DWORD
  239. key as CompletionKey: ULONG_PTR
  240. address as Overlapped: OVERLAPPED
  241. /
  242. Post a message to completion port.
  243. [clinic start generated code]*/
  244. static PyObject *
  245. _overlapped_PostQueuedCompletionStatus_impl(PyObject *module,
  246. HANDLE CompletionPort,
  247. DWORD NumberOfBytes,
  248. ULONG_PTR CompletionKey,
  249. OVERLAPPED *Overlapped)
  250. /*[clinic end generated code: output=93e73f2933a43e9e input=e936202d87937aca]*/
  251. {
  252. BOOL ret;
  253. Py_BEGIN_ALLOW_THREADS
  254. ret = PostQueuedCompletionStatus(CompletionPort, NumberOfBytes,
  255. CompletionKey, Overlapped);
  256. Py_END_ALLOW_THREADS
  257. if (!ret)
  258. return SetFromWindowsErr(0);
  259. Py_RETURN_NONE;
  260. }
  261. /*
  262. * Wait for a handle
  263. */
  264. struct PostCallbackData {
  265. HANDLE CompletionPort;
  266. LPOVERLAPPED Overlapped;
  267. };
  268. static VOID CALLBACK
  269. PostToQueueCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
  270. {
  271. struct PostCallbackData *p = (struct PostCallbackData*) lpParameter;
  272. PostQueuedCompletionStatus(p->CompletionPort, TimerOrWaitFired,
  273. 0, p->Overlapped);
  274. /* ignore possible error! */
  275. PyMem_RawFree(p);
  276. }
  277. /*[clinic input]
  278. _overlapped.RegisterWaitWithQueue
  279. Object: HANDLE
  280. CompletionPort: HANDLE
  281. Overlapped: OVERLAPPED
  282. Timeout as Milliseconds: DWORD
  283. /
  284. Register wait for Object; when complete CompletionPort is notified.
  285. [clinic start generated code]*/
  286. static PyObject *
  287. _overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object,
  288. HANDLE CompletionPort,
  289. OVERLAPPED *Overlapped,
  290. DWORD Milliseconds)
  291. /*[clinic end generated code: output=c2ace732e447fe45 input=2dd4efee44abe8ee]*/
  292. {
  293. HANDLE NewWaitObject;
  294. struct PostCallbackData data = {CompletionPort, Overlapped}, *pdata;
  295. /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since
  296. PostToQueueCallback() will call PyMem_Free() from a new C thread
  297. which doesn't hold the GIL. */
  298. pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData));
  299. if (pdata == NULL)
  300. return SetFromWindowsErr(0);
  301. *pdata = data;
  302. if (!RegisterWaitForSingleObject(
  303. &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds,
  304. WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE))
  305. {
  306. SetFromWindowsErr(0);
  307. PyMem_RawFree(pdata);
  308. return NULL;
  309. }
  310. return Py_BuildValue(F_HANDLE, NewWaitObject);
  311. }
  312. /*[clinic input]
  313. _overlapped.UnregisterWait
  314. WaitHandle: HANDLE
  315. /
  316. Unregister wait handle.
  317. [clinic start generated code]*/
  318. static PyObject *
  319. _overlapped_UnregisterWait_impl(PyObject *module, HANDLE WaitHandle)
  320. /*[clinic end generated code: output=ec90cd955a9a617d input=a56709544cb2df0f]*/
  321. {
  322. BOOL ret;
  323. Py_BEGIN_ALLOW_THREADS
  324. ret = UnregisterWait(WaitHandle);
  325. Py_END_ALLOW_THREADS
  326. if (!ret)
  327. return SetFromWindowsErr(0);
  328. Py_RETURN_NONE;
  329. }
  330. /*[clinic input]
  331. _overlapped.UnregisterWaitEx
  332. WaitHandle: HANDLE
  333. Event: HANDLE
  334. /
  335. Unregister wait handle.
  336. [clinic start generated code]*/
  337. static PyObject *
  338. _overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle,
  339. HANDLE Event)
  340. /*[clinic end generated code: output=2e3d84c1d5f65b92 input=953cddc1de50fab9]*/
  341. {
  342. BOOL ret;
  343. Py_BEGIN_ALLOW_THREADS
  344. ret = UnregisterWaitEx(WaitHandle, Event);
  345. Py_END_ALLOW_THREADS
  346. if (!ret)
  347. return SetFromWindowsErr(0);
  348. Py_RETURN_NONE;
  349. }
  350. /*
  351. * Event functions -- currently only used by tests
  352. */
  353. /*[clinic input]
  354. _overlapped.CreateEvent
  355. EventAttributes: object
  356. ManualReset: BOOL
  357. InitialState: BOOL
  358. Name: Py_UNICODE(accept={str, NoneType})
  359. /
  360. Create an event.
  361. EventAttributes must be None.
  362. [clinic start generated code]*/
  363. static PyObject *
  364. _overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes,
  365. BOOL ManualReset, BOOL InitialState,
  366. const Py_UNICODE *Name)
  367. /*[clinic end generated code: output=8e04f0916c17b13d input=dbc36ae14375ba24]*/
  368. {
  369. HANDLE Event;
  370. if (EventAttributes != Py_None) {
  371. PyErr_SetString(PyExc_ValueError, "EventAttributes must be None");
  372. return NULL;
  373. }
  374. Py_BEGIN_ALLOW_THREADS
  375. Event = CreateEventW(NULL, ManualReset, InitialState, Name);
  376. Py_END_ALLOW_THREADS
  377. if (Event == NULL)
  378. return SetFromWindowsErr(0);
  379. return Py_BuildValue(F_HANDLE, Event);
  380. }
  381. /*[clinic input]
  382. _overlapped.SetEvent
  383. Handle: HANDLE
  384. /
  385. Set event.
  386. [clinic start generated code]*/
  387. static PyObject *
  388. _overlapped_SetEvent_impl(PyObject *module, HANDLE Handle)
  389. /*[clinic end generated code: output=5b8d974216b0e569 input=d8b0d26eb7391e80]*/
  390. {
  391. BOOL ret;
  392. Py_BEGIN_ALLOW_THREADS
  393. ret = SetEvent(Handle);
  394. Py_END_ALLOW_THREADS
  395. if (!ret)
  396. return SetFromWindowsErr(0);
  397. Py_RETURN_NONE;
  398. }
  399. /*[clinic input]
  400. _overlapped.ResetEvent
  401. Handle: HANDLE
  402. /
  403. Reset event.
  404. [clinic start generated code]*/
  405. static PyObject *
  406. _overlapped_ResetEvent_impl(PyObject *module, HANDLE Handle)
  407. /*[clinic end generated code: output=066537a8405cddb2 input=d4e089c9ba84ff2f]*/
  408. {
  409. BOOL ret;
  410. Py_BEGIN_ALLOW_THREADS
  411. ret = ResetEvent(Handle);
  412. Py_END_ALLOW_THREADS
  413. if (!ret)
  414. return SetFromWindowsErr(0);
  415. Py_RETURN_NONE;
  416. }
  417. /*
  418. * Bind socket handle to local port without doing slow getaddrinfo()
  419. */
  420. /*[clinic input]
  421. _overlapped.BindLocal
  422. handle as Socket: HANDLE
  423. family as Family: int
  424. /
  425. Bind a socket handle to an arbitrary local port.
  426. family should be AF_INET or AF_INET6.
  427. [clinic start generated code]*/
  428. static PyObject *
  429. _overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family)
  430. /*[clinic end generated code: output=edb93862697aed9c input=a0e7b5c2f541170c]*/
  431. {
  432. BOOL ret;
  433. if (Family == AF_INET) {
  434. struct sockaddr_in addr;
  435. memset(&addr, 0, sizeof(addr));
  436. addr.sin_family = AF_INET;
  437. addr.sin_port = 0;
  438. addr.sin_addr.S_un.S_addr = INADDR_ANY;
  439. ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr))
  440. != SOCKET_ERROR;
  441. } else if (Family == AF_INET6) {
  442. struct sockaddr_in6 addr;
  443. memset(&addr, 0, sizeof(addr));
  444. addr.sin6_family = AF_INET6;
  445. addr.sin6_port = 0;
  446. addr.sin6_addr = in6addr_any;
  447. ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr))
  448. != SOCKET_ERROR;
  449. } else {
  450. PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4");
  451. return NULL;
  452. }
  453. if (!ret)
  454. return SetFromWindowsErr(WSAGetLastError());
  455. Py_RETURN_NONE;
  456. }
  457. /*
  458. * Windows equivalent of os.strerror() -- compare _ctypes/callproc.c
  459. */
  460. /*[clinic input]
  461. _overlapped.FormatMessage
  462. error_code as code: DWORD
  463. /
  464. Return error message for an error code.
  465. [clinic start generated code]*/
  466. static PyObject *
  467. _overlapped_FormatMessage_impl(PyObject *module, DWORD code)
  468. /*[clinic end generated code: output=02c964ff22407c6b input=644bb5b80326179e]*/
  469. {
  470. DWORD n;
  471. WCHAR *lpMsgBuf;
  472. PyObject *res;
  473. n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  474. FORMAT_MESSAGE_FROM_SYSTEM |
  475. FORMAT_MESSAGE_IGNORE_INSERTS,
  476. NULL,
  477. code,
  478. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  479. (LPWSTR) &lpMsgBuf,
  480. 0,
  481. NULL);
  482. if (n) {
  483. while (iswspace(lpMsgBuf[n-1]))
  484. --n;
  485. lpMsgBuf[n] = L'\0';
  486. res = Py_BuildValue("u", lpMsgBuf);
  487. } else {
  488. res = PyUnicode_FromFormat("unknown error code %u", code);
  489. }
  490. LocalFree(lpMsgBuf);
  491. return res;
  492. }
  493. /*
  494. * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE
  495. */
  496. static inline void
  497. mark_as_completed(OVERLAPPED *ov)
  498. {
  499. ov->Internal = 0;
  500. if (ov->hEvent != NULL)
  501. SetEvent(ov->hEvent);
  502. }
  503. /*
  504. * A Python object wrapping an OVERLAPPED structure and other useful data
  505. * for overlapped I/O
  506. */
  507. /*[clinic input]
  508. @classmethod
  509. _overlapped.Overlapped.__new__
  510. event: HANDLE(c_default='INVALID_HANDLE_VALUE') = _overlapped.INVALID_HANDLE_VALUE
  511. OVERLAPPED structure wrapper.
  512. [clinic start generated code]*/
  513. static PyObject *
  514. _overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event)
  515. /*[clinic end generated code: output=6da60504a18eb421 input=26b8a7429e629e95]*/
  516. {
  517. OverlappedObject *self;
  518. if (event == INVALID_HANDLE_VALUE) {
  519. event = CreateEvent(NULL, TRUE, FALSE, NULL);
  520. if (event == NULL)
  521. return SetFromWindowsErr(0);
  522. }
  523. self = PyObject_New(OverlappedObject, type);
  524. if (self == NULL) {
  525. if (event != NULL)
  526. CloseHandle(event);
  527. return NULL;
  528. }
  529. self->handle = NULL;
  530. self->error = 0;
  531. self->type = TYPE_NONE;
  532. self->allocated_buffer = NULL;
  533. memset(&self->overlapped, 0, sizeof(OVERLAPPED));
  534. memset(&self->user_buffer, 0, sizeof(Py_buffer));
  535. if (event)
  536. self->overlapped.hEvent = event;
  537. return (PyObject *)self;
  538. }
  539. /* Note (bpo-32710): OverlappedType.tp_clear is not defined to not release
  540. buffers while overlapped are still running, to prevent a crash. */
  541. static int
  542. Overlapped_clear(OverlappedObject *self)
  543. {
  544. switch (self->type) {
  545. case TYPE_READ:
  546. case TYPE_ACCEPT: {
  547. Py_CLEAR(self->allocated_buffer);
  548. break;
  549. }
  550. case TYPE_READ_FROM: {
  551. // An initial call to WSARecvFrom will only allocate the buffer.
  552. // The result tuple of (message, address) is only
  553. // allocated _after_ a message has been received.
  554. if(self->read_from.result) {
  555. // We've received a message, free the result tuple.
  556. Py_CLEAR(self->read_from.result);
  557. }
  558. if(self->read_from.allocated_buffer) {
  559. Py_CLEAR(self->read_from.allocated_buffer);
  560. }
  561. break;
  562. }
  563. case TYPE_READ_FROM_INTO: {
  564. if (self->read_from_into.result) {
  565. // We've received a message, free the result tuple.
  566. Py_CLEAR(self->read_from_into.result);
  567. }
  568. if (self->read_from_into.user_buffer.obj) {
  569. PyBuffer_Release(&self->read_from_into.user_buffer);
  570. }
  571. break;
  572. }
  573. case TYPE_WRITE:
  574. case TYPE_WRITE_TO:
  575. case TYPE_READINTO: {
  576. if (self->user_buffer.obj) {
  577. PyBuffer_Release(&self->user_buffer);
  578. }
  579. break;
  580. }
  581. }
  582. self->type = TYPE_NOT_STARTED;
  583. return 0;
  584. }
  585. static void
  586. Overlapped_dealloc(OverlappedObject *self)
  587. {
  588. DWORD bytes;
  589. DWORD olderr = GetLastError();
  590. BOOL wait = FALSE;
  591. BOOL ret;
  592. if (!HasOverlappedIoCompleted(&self->overlapped) &&
  593. self->type != TYPE_NOT_STARTED)
  594. {
  595. // NOTE: We should not get here, if we do then something is wrong in
  596. // the IocpProactor or ProactorEventLoop. Since everything uses IOCP if
  597. // the overlapped IO hasn't completed yet then we should not be
  598. // deallocating!
  599. //
  600. // The problem is likely that this OverlappedObject was removed from
  601. // the IocpProactor._cache before it was complete. The _cache holds a
  602. // reference while IO is pending so that it does not get deallocated
  603. // while the kernel has retained the OVERLAPPED structure.
  604. //
  605. // CancelIoEx (likely called from self.cancel()) may have successfully
  606. // completed, but the OVERLAPPED is still in use until either
  607. // HasOverlappedIoCompleted() is true or GetQueuedCompletionStatus has
  608. // returned this OVERLAPPED object.
  609. //
  610. // NOTE: Waiting when IOCP is in use can hang indefinitely, but this
  611. // CancelIoEx is superfluous in that self.cancel() was already called,
  612. // so I've only ever seen this return FALSE with GLE=ERROR_NOT_FOUND
  613. Py_BEGIN_ALLOW_THREADS
  614. if (CancelIoEx(self->handle, &self->overlapped))
  615. wait = TRUE;
  616. ret = GetOverlappedResult(self->handle, &self->overlapped,
  617. &bytes, wait);
  618. Py_END_ALLOW_THREADS
  619. switch (ret ? ERROR_SUCCESS : GetLastError()) {
  620. case ERROR_SUCCESS:
  621. case ERROR_NOT_FOUND:
  622. case ERROR_OPERATION_ABORTED:
  623. break;
  624. default:
  625. PyErr_Format(
  626. PyExc_RuntimeError,
  627. "%R still has pending operation at "
  628. "deallocation, the process may crash", self);
  629. PyErr_WriteUnraisable(NULL);
  630. }
  631. }
  632. if (self->overlapped.hEvent != NULL) {
  633. CloseHandle(self->overlapped.hEvent);
  634. }
  635. Overlapped_clear(self);
  636. SetLastError(olderr);
  637. PyTypeObject *tp = Py_TYPE(self);
  638. PyObject_Free(self);
  639. Py_DECREF(tp);
  640. }
  641. /* Convert IPv4 sockaddr to a Python str. */
  642. static PyObject *
  643. make_ipv4_addr(const struct sockaddr_in *addr)
  644. {
  645. char buf[INET_ADDRSTRLEN];
  646. if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) {
  647. PyErr_SetFromErrno(PyExc_OSError);
  648. return NULL;
  649. }
  650. return PyUnicode_FromString(buf);
  651. }
  652. /* Convert IPv6 sockaddr to a Python str. */
  653. static PyObject *
  654. make_ipv6_addr(const struct sockaddr_in6 *addr)
  655. {
  656. char buf[INET6_ADDRSTRLEN];
  657. if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) {
  658. PyErr_SetFromErrno(PyExc_OSError);
  659. return NULL;
  660. }
  661. return PyUnicode_FromString(buf);
  662. }
  663. static PyObject*
  664. unparse_address(LPSOCKADDR Address, DWORD Length)
  665. {
  666. /* The function is adopted from mocketmodule.c makesockaddr()*/
  667. switch(Address->sa_family) {
  668. case AF_INET: {
  669. const struct sockaddr_in *a = (const struct sockaddr_in *)Address;
  670. PyObject *addrobj = make_ipv4_addr(a);
  671. PyObject *ret = NULL;
  672. if (addrobj) {
  673. ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
  674. Py_DECREF(addrobj);
  675. }
  676. return ret;
  677. }
  678. case AF_INET6: {
  679. const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)Address;
  680. PyObject *addrobj = make_ipv6_addr(a);
  681. PyObject *ret = NULL;
  682. if (addrobj) {
  683. ret = Py_BuildValue("OiII",
  684. addrobj,
  685. ntohs(a->sin6_port),
  686. ntohl(a->sin6_flowinfo),
  687. a->sin6_scope_id);
  688. Py_DECREF(addrobj);
  689. }
  690. return ret;
  691. }
  692. default: {
  693. PyErr_SetString(PyExc_ValueError, "recvfrom returned unsupported address family");
  694. return NULL;
  695. }
  696. }
  697. }
  698. /*[clinic input]
  699. _overlapped.Overlapped.cancel
  700. Cancel overlapped operation.
  701. [clinic start generated code]*/
  702. static PyObject *
  703. _overlapped_Overlapped_cancel_impl(OverlappedObject *self)
  704. /*[clinic end generated code: output=54ad7aeece89901c input=80eb67c7b57dbcf1]*/
  705. {
  706. BOOL ret = TRUE;
  707. if (self->type == TYPE_NOT_STARTED
  708. || self->type == TYPE_WAIT_NAMED_PIPE_AND_CONNECT)
  709. Py_RETURN_NONE;
  710. if (!HasOverlappedIoCompleted(&self->overlapped)) {
  711. Py_BEGIN_ALLOW_THREADS
  712. ret = CancelIoEx(self->handle, &self->overlapped);
  713. Py_END_ALLOW_THREADS
  714. }
  715. /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */
  716. if (!ret && GetLastError() != ERROR_NOT_FOUND)
  717. return SetFromWindowsErr(0);
  718. Py_RETURN_NONE;
  719. }
  720. /*[clinic input]
  721. _overlapped.Overlapped.getresult
  722. wait: BOOL(c_default='FALSE') = False
  723. /
  724. Retrieve result of operation.
  725. If wait is true then it blocks until the operation is finished. If wait
  726. is false and the operation is still pending then an error is raised.
  727. [clinic start generated code]*/
  728. static PyObject *
  729. _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait)
  730. /*[clinic end generated code: output=8c9bd04d08994f6c input=aa5b03e9897ca074]*/
  731. {
  732. DWORD transferred = 0;
  733. BOOL ret;
  734. DWORD err;
  735. PyObject *addr;
  736. if (self->type == TYPE_NONE) {
  737. PyErr_SetString(PyExc_ValueError, "operation not yet attempted");
  738. return NULL;
  739. }
  740. if (self->type == TYPE_NOT_STARTED) {
  741. PyErr_SetString(PyExc_ValueError, "operation failed to start");
  742. return NULL;
  743. }
  744. Py_BEGIN_ALLOW_THREADS
  745. ret = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
  746. wait);
  747. Py_END_ALLOW_THREADS
  748. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  749. switch (err) {
  750. case ERROR_SUCCESS:
  751. case ERROR_MORE_DATA:
  752. break;
  753. case ERROR_BROKEN_PIPE:
  754. if (self->type == TYPE_READ || self->type == TYPE_READINTO) {
  755. break;
  756. }
  757. else if (self->type == TYPE_READ_FROM &&
  758. (self->read_from.result != NULL ||
  759. self->read_from.allocated_buffer != NULL))
  760. {
  761. break;
  762. }
  763. else if (self->type == TYPE_READ_FROM_INTO &&
  764. self->read_from_into.result != NULL)
  765. {
  766. break;
  767. }
  768. /* fall through */
  769. default:
  770. return SetFromWindowsErr(err);
  771. }
  772. switch (self->type) {
  773. case TYPE_READ:
  774. assert(PyBytes_CheckExact(self->allocated_buffer));
  775. if (transferred != PyBytes_GET_SIZE(self->allocated_buffer) &&
  776. _PyBytes_Resize(&self->allocated_buffer, transferred))
  777. return NULL;
  778. return Py_NewRef(self->allocated_buffer);
  779. case TYPE_READ_FROM:
  780. assert(PyBytes_CheckExact(self->read_from.allocated_buffer));
  781. if (transferred != PyBytes_GET_SIZE(
  782. self->read_from.allocated_buffer) &&
  783. _PyBytes_Resize(&self->read_from.allocated_buffer, transferred))
  784. {
  785. return NULL;
  786. }
  787. // unparse the address
  788. addr = unparse_address((SOCKADDR*)&self->read_from.address,
  789. self->read_from.address_length);
  790. if (addr == NULL) {
  791. return NULL;
  792. }
  793. // The result is a two item tuple: (message, address)
  794. self->read_from.result = PyTuple_New(2);
  795. if (self->read_from.result == NULL) {
  796. Py_CLEAR(addr);
  797. return NULL;
  798. }
  799. // first item: message
  800. PyTuple_SET_ITEM(self->read_from.result, 0,
  801. Py_NewRef(self->read_from.allocated_buffer));
  802. // second item: address
  803. PyTuple_SET_ITEM(self->read_from.result, 1, addr);
  804. return Py_NewRef(self->read_from.result);
  805. case TYPE_READ_FROM_INTO:
  806. // unparse the address
  807. addr = unparse_address((SOCKADDR*)&self->read_from_into.address,
  808. self->read_from_into.address_length);
  809. if (addr == NULL) {
  810. return NULL;
  811. }
  812. // The result is a two item tuple: (number of bytes read, address)
  813. self->read_from_into.result = PyTuple_New(2);
  814. if (self->read_from_into.result == NULL) {
  815. Py_CLEAR(addr);
  816. return NULL;
  817. }
  818. // first item: number of bytes read
  819. PyTuple_SET_ITEM(self->read_from_into.result, 0,
  820. PyLong_FromUnsignedLong((unsigned long)transferred));
  821. // second item: address
  822. PyTuple_SET_ITEM(self->read_from_into.result, 1, addr);
  823. return Py_NewRef(self->read_from_into.result);
  824. default:
  825. return PyLong_FromUnsignedLong((unsigned long) transferred);
  826. }
  827. }
  828. static PyObject *
  829. do_ReadFile(OverlappedObject *self, HANDLE handle,
  830. char *bufstart, DWORD buflen)
  831. {
  832. DWORD nread;
  833. int ret;
  834. DWORD err;
  835. Py_BEGIN_ALLOW_THREADS
  836. ret = ReadFile(handle, bufstart, buflen, &nread,
  837. &self->overlapped);
  838. Py_END_ALLOW_THREADS
  839. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  840. switch (err) {
  841. case ERROR_BROKEN_PIPE:
  842. mark_as_completed(&self->overlapped);
  843. return SetFromWindowsErr(err);
  844. case ERROR_SUCCESS:
  845. case ERROR_MORE_DATA:
  846. case ERROR_IO_PENDING:
  847. Py_RETURN_NONE;
  848. default:
  849. Overlapped_clear(self);
  850. return SetFromWindowsErr(err);
  851. }
  852. }
  853. /*[clinic input]
  854. _overlapped.Overlapped.ReadFile
  855. handle: HANDLE
  856. size: DWORD
  857. /
  858. Start overlapped read.
  859. [clinic start generated code]*/
  860. static PyObject *
  861. _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle,
  862. DWORD size)
  863. /*[clinic end generated code: output=4c8557e16941e4ae input=98c495baa0342425]*/
  864. {
  865. PyObject *buf;
  866. if (self->type != TYPE_NONE) {
  867. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  868. return NULL;
  869. }
  870. #if SIZEOF_SIZE_T <= SIZEOF_LONG
  871. size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
  872. #endif
  873. buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
  874. if (buf == NULL)
  875. return NULL;
  876. self->type = TYPE_READ;
  877. self->handle = handle;
  878. self->allocated_buffer = buf;
  879. return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size);
  880. }
  881. /*[clinic input]
  882. _overlapped.Overlapped.ReadFileInto
  883. handle: HANDLE
  884. buf as bufobj: Py_buffer
  885. /
  886. Start overlapped receive.
  887. [clinic start generated code]*/
  888. static PyObject *
  889. _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self,
  890. HANDLE handle, Py_buffer *bufobj)
  891. /*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/
  892. {
  893. if (self->type != TYPE_NONE) {
  894. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  895. return NULL;
  896. }
  897. #if SIZEOF_SIZE_T > SIZEOF_LONG
  898. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  899. PyErr_SetString(PyExc_ValueError, "buffer too large");
  900. return NULL;
  901. }
  902. #endif
  903. steal_buffer(&self->user_buffer, bufobj);
  904. self->type = TYPE_READINTO;
  905. self->handle = handle;
  906. return do_ReadFile(self, handle, self->user_buffer.buf,
  907. (DWORD)self->user_buffer.len);
  908. }
  909. static PyObject *
  910. do_WSARecv(OverlappedObject *self, HANDLE handle,
  911. char *bufstart, DWORD buflen, DWORD flags)
  912. {
  913. DWORD nread;
  914. WSABUF wsabuf;
  915. int ret;
  916. DWORD err;
  917. wsabuf.buf = bufstart;
  918. wsabuf.len = buflen;
  919. Py_BEGIN_ALLOW_THREADS
  920. ret = WSARecv((SOCKET)handle, &wsabuf, 1, &nread, &flags,
  921. &self->overlapped, NULL);
  922. Py_END_ALLOW_THREADS
  923. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  924. switch (err) {
  925. case ERROR_BROKEN_PIPE:
  926. mark_as_completed(&self->overlapped);
  927. return SetFromWindowsErr(err);
  928. case ERROR_SUCCESS:
  929. case ERROR_MORE_DATA:
  930. case ERROR_IO_PENDING:
  931. Py_RETURN_NONE;
  932. default:
  933. Overlapped_clear(self);
  934. return SetFromWindowsErr(err);
  935. }
  936. }
  937. /*[clinic input]
  938. _overlapped.Overlapped.WSARecv
  939. handle: HANDLE
  940. size: DWORD
  941. flags: DWORD = 0
  942. /
  943. Start overlapped receive.
  944. [clinic start generated code]*/
  945. static PyObject *
  946. _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle,
  947. DWORD size, DWORD flags)
  948. /*[clinic end generated code: output=3a5e9c61ff040906 input=8c04e506cc3d741a]*/
  949. {
  950. PyObject *buf;
  951. if (self->type != TYPE_NONE) {
  952. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  953. return NULL;
  954. }
  955. #if SIZEOF_SIZE_T <= SIZEOF_LONG
  956. size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
  957. #endif
  958. buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
  959. if (buf == NULL)
  960. return NULL;
  961. self->type = TYPE_READ;
  962. self->handle = handle;
  963. self->allocated_buffer = buf;
  964. return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags);
  965. }
  966. /*[clinic input]
  967. _overlapped.Overlapped.WSARecvInto
  968. handle: HANDLE
  969. buf as bufobj: Py_buffer
  970. flags: DWORD
  971. /
  972. Start overlapped receive.
  973. [clinic start generated code]*/
  974. static PyObject *
  975. _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
  976. HANDLE handle, Py_buffer *bufobj,
  977. DWORD flags)
  978. /*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/
  979. {
  980. if (self->type != TYPE_NONE) {
  981. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  982. return NULL;
  983. }
  984. #if SIZEOF_SIZE_T > SIZEOF_LONG
  985. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  986. PyErr_SetString(PyExc_ValueError, "buffer too large");
  987. return NULL;
  988. }
  989. #endif
  990. steal_buffer(&self->user_buffer, bufobj);
  991. self->type = TYPE_READINTO;
  992. self->handle = handle;
  993. return do_WSARecv(self, handle, self->user_buffer.buf,
  994. (DWORD)self->user_buffer.len, flags);
  995. }
  996. /*[clinic input]
  997. _overlapped.Overlapped.WriteFile
  998. handle: HANDLE
  999. buf as bufobj: Py_buffer
  1000. /
  1001. Start overlapped write.
  1002. [clinic start generated code]*/
  1003. static PyObject *
  1004. _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
  1005. Py_buffer *bufobj)
  1006. /*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/
  1007. {
  1008. DWORD written;
  1009. BOOL ret;
  1010. DWORD err;
  1011. if (self->type != TYPE_NONE) {
  1012. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1013. return NULL;
  1014. }
  1015. #if SIZEOF_SIZE_T > SIZEOF_LONG
  1016. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  1017. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1018. return NULL;
  1019. }
  1020. #endif
  1021. steal_buffer(&self->user_buffer, bufobj);
  1022. self->type = TYPE_WRITE;
  1023. self->handle = handle;
  1024. Py_BEGIN_ALLOW_THREADS
  1025. ret = WriteFile(handle, self->user_buffer.buf,
  1026. (DWORD)self->user_buffer.len,
  1027. &written, &self->overlapped);
  1028. Py_END_ALLOW_THREADS
  1029. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  1030. switch (err) {
  1031. case ERROR_SUCCESS:
  1032. case ERROR_IO_PENDING:
  1033. Py_RETURN_NONE;
  1034. default:
  1035. Overlapped_clear(self);
  1036. return SetFromWindowsErr(err);
  1037. }
  1038. }
  1039. /*[clinic input]
  1040. _overlapped.Overlapped.WSASend
  1041. handle: HANDLE
  1042. buf as bufobj: Py_buffer
  1043. flags: DWORD
  1044. /
  1045. Start overlapped send.
  1046. [clinic start generated code]*/
  1047. static PyObject *
  1048. _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
  1049. Py_buffer *bufobj, DWORD flags)
  1050. /*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/
  1051. {
  1052. DWORD written;
  1053. WSABUF wsabuf;
  1054. int ret;
  1055. DWORD err;
  1056. if (self->type != TYPE_NONE) {
  1057. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1058. return NULL;
  1059. }
  1060. #if SIZEOF_SIZE_T > SIZEOF_LONG
  1061. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  1062. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1063. return NULL;
  1064. }
  1065. #endif
  1066. steal_buffer(&self->user_buffer, bufobj);
  1067. self->type = TYPE_WRITE;
  1068. self->handle = handle;
  1069. wsabuf.len = (DWORD)self->user_buffer.len;
  1070. wsabuf.buf = self->user_buffer.buf;
  1071. Py_BEGIN_ALLOW_THREADS
  1072. ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags,
  1073. &self->overlapped, NULL);
  1074. Py_END_ALLOW_THREADS
  1075. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  1076. switch (err) {
  1077. case ERROR_SUCCESS:
  1078. case ERROR_IO_PENDING:
  1079. Py_RETURN_NONE;
  1080. default:
  1081. Overlapped_clear(self);
  1082. return SetFromWindowsErr(err);
  1083. }
  1084. }
  1085. /*[clinic input]
  1086. _overlapped.Overlapped.AcceptEx
  1087. listen_handle as ListenSocket: HANDLE
  1088. accept_handle as AcceptSocket: HANDLE
  1089. /
  1090. Start overlapped wait for client to connect.
  1091. [clinic start generated code]*/
  1092. static PyObject *
  1093. _overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self,
  1094. HANDLE ListenSocket,
  1095. HANDLE AcceptSocket)
  1096. /*[clinic end generated code: output=9a7381d4232af889 input=b83473224fc3a1c5]*/
  1097. {
  1098. DWORD BytesReceived;
  1099. DWORD size;
  1100. PyObject *buf;
  1101. BOOL ret;
  1102. DWORD err;
  1103. if (self->type != TYPE_NONE) {
  1104. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1105. return NULL;
  1106. }
  1107. size = sizeof(struct sockaddr_in6) + 16;
  1108. buf = PyBytes_FromStringAndSize(NULL, size*2);
  1109. if (!buf)
  1110. return NULL;
  1111. self->type = TYPE_ACCEPT;
  1112. self->handle = ListenSocket;
  1113. self->allocated_buffer = buf;
  1114. Py_BEGIN_ALLOW_THREADS
  1115. ret = Py_AcceptEx((SOCKET)ListenSocket, (SOCKET)AcceptSocket,
  1116. PyBytes_AS_STRING(buf), 0, size, size, &BytesReceived,
  1117. &self->overlapped);
  1118. Py_END_ALLOW_THREADS
  1119. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1120. switch (err) {
  1121. case ERROR_SUCCESS:
  1122. case ERROR_IO_PENDING:
  1123. Py_RETURN_NONE;
  1124. default:
  1125. Overlapped_clear(self);
  1126. return SetFromWindowsErr(err);
  1127. }
  1128. }
  1129. static int
  1130. parse_address(PyObject *obj, SOCKADDR *Address, int Length)
  1131. {
  1132. PyObject *Host_obj;
  1133. wchar_t *Host;
  1134. unsigned short Port;
  1135. unsigned long FlowInfo;
  1136. unsigned long ScopeId;
  1137. memset(Address, 0, Length);
  1138. switch (PyTuple_GET_SIZE(obj)) {
  1139. case 2: {
  1140. if (!PyArg_ParseTuple(obj, "UH", &Host_obj, &Port)) {
  1141. return -1;
  1142. }
  1143. Host = PyUnicode_AsWideCharString(Host_obj, NULL);
  1144. if (Host == NULL) {
  1145. return -1;
  1146. }
  1147. Address->sa_family = AF_INET;
  1148. if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) {
  1149. SetFromWindowsErr(WSAGetLastError());
  1150. Length = -1;
  1151. }
  1152. else {
  1153. ((SOCKADDR_IN*)Address)->sin_port = htons(Port);
  1154. }
  1155. PyMem_Free(Host);
  1156. return Length;
  1157. }
  1158. case 4: {
  1159. if (!PyArg_ParseTuple(obj,
  1160. "UHkk;ConnectEx(): illegal address_as_bytes argument",
  1161. &Host_obj, &Port, &FlowInfo, &ScopeId))
  1162. {
  1163. return -1;
  1164. }
  1165. Host = PyUnicode_AsWideCharString(Host_obj, NULL);
  1166. if (Host == NULL) {
  1167. return -1;
  1168. }
  1169. Address->sa_family = AF_INET6;
  1170. if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) {
  1171. SetFromWindowsErr(WSAGetLastError());
  1172. Length = -1;
  1173. }
  1174. else {
  1175. ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port);
  1176. ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo;
  1177. ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId;
  1178. }
  1179. PyMem_Free(Host);
  1180. return Length;
  1181. }
  1182. default:
  1183. PyErr_SetString(PyExc_ValueError, "illegal address_as_bytes argument");
  1184. return -1;
  1185. }
  1186. }
  1187. /*[clinic input]
  1188. _overlapped.Overlapped.ConnectEx
  1189. client_handle as ConnectSocket: HANDLE
  1190. address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
  1191. /
  1192. Start overlapped connect.
  1193. client_handle should be unbound.
  1194. [clinic start generated code]*/
  1195. static PyObject *
  1196. _overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self,
  1197. HANDLE ConnectSocket,
  1198. PyObject *AddressObj)
  1199. /*[clinic end generated code: output=5aebbbdb4f022833 input=d6bbd2d84b156fc1]*/
  1200. {
  1201. char AddressBuf[sizeof(struct sockaddr_in6)];
  1202. SOCKADDR *Address = (SOCKADDR*)AddressBuf;
  1203. int Length;
  1204. BOOL ret;
  1205. DWORD err;
  1206. if (self->type != TYPE_NONE) {
  1207. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1208. return NULL;
  1209. }
  1210. Length = sizeof(AddressBuf);
  1211. Length = parse_address(AddressObj, Address, Length);
  1212. if (Length < 0)
  1213. return NULL;
  1214. self->type = TYPE_CONNECT;
  1215. self->handle = ConnectSocket;
  1216. Py_BEGIN_ALLOW_THREADS
  1217. ret = Py_ConnectEx((SOCKET)ConnectSocket, Address, Length,
  1218. NULL, 0, NULL, &self->overlapped);
  1219. Py_END_ALLOW_THREADS
  1220. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1221. switch (err) {
  1222. case ERROR_SUCCESS:
  1223. case ERROR_IO_PENDING:
  1224. Py_RETURN_NONE;
  1225. default:
  1226. Overlapped_clear(self);
  1227. return SetFromWindowsErr(err);
  1228. }
  1229. }
  1230. /*[clinic input]
  1231. _overlapped.Overlapped.DisconnectEx
  1232. handle as Socket: HANDLE
  1233. flags: DWORD
  1234. /
  1235. [clinic start generated code]*/
  1236. static PyObject *
  1237. _overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self,
  1238. HANDLE Socket, DWORD flags)
  1239. /*[clinic end generated code: output=8d64ddb8c93c2126 input=680845cdcdf820eb]*/
  1240. {
  1241. BOOL ret;
  1242. DWORD err;
  1243. if (self->type != TYPE_NONE) {
  1244. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1245. return NULL;
  1246. }
  1247. self->type = TYPE_DISCONNECT;
  1248. self->handle = Socket;
  1249. Py_BEGIN_ALLOW_THREADS
  1250. ret = Py_DisconnectEx((SOCKET)Socket, &self->overlapped, flags, 0);
  1251. Py_END_ALLOW_THREADS
  1252. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1253. switch (err) {
  1254. case ERROR_SUCCESS:
  1255. case ERROR_IO_PENDING:
  1256. Py_RETURN_NONE;
  1257. default:
  1258. Overlapped_clear(self);
  1259. return SetFromWindowsErr(err);
  1260. }
  1261. }
  1262. /*[clinic input]
  1263. _overlapped.Overlapped.TransmitFile
  1264. socket as Socket: HANDLE
  1265. file as File: HANDLE
  1266. offset: DWORD
  1267. offset_high: DWORD
  1268. count_to_write: DWORD
  1269. count_per_send: DWORD
  1270. flags: DWORD
  1271. /
  1272. Transmit file data over a connected socket.
  1273. [clinic start generated code]*/
  1274. static PyObject *
  1275. _overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self,
  1276. HANDLE Socket, HANDLE File,
  1277. DWORD offset, DWORD offset_high,
  1278. DWORD count_to_write,
  1279. DWORD count_per_send, DWORD flags)
  1280. /*[clinic end generated code: output=03f3ca5512e678fd input=7e6f97b391f60e8c]*/
  1281. {
  1282. BOOL ret;
  1283. DWORD err;
  1284. if (self->type != TYPE_NONE) {
  1285. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1286. return NULL;
  1287. }
  1288. self->type = TYPE_TRANSMIT_FILE;
  1289. self->handle = Socket;
  1290. self->overlapped.Offset = offset;
  1291. self->overlapped.OffsetHigh = offset_high;
  1292. Py_BEGIN_ALLOW_THREADS
  1293. ret = Py_TransmitFile((SOCKET)Socket, File, count_to_write,
  1294. count_per_send, &self->overlapped, NULL, flags);
  1295. Py_END_ALLOW_THREADS
  1296. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1297. switch (err) {
  1298. case ERROR_SUCCESS:
  1299. case ERROR_IO_PENDING:
  1300. Py_RETURN_NONE;
  1301. default:
  1302. Overlapped_clear(self);
  1303. return SetFromWindowsErr(err);
  1304. }
  1305. }
  1306. /*[clinic input]
  1307. _overlapped.Overlapped.ConnectNamedPipe
  1308. handle as Pipe: HANDLE
  1309. /
  1310. Start overlapped wait for a client to connect.
  1311. [clinic start generated code]*/
  1312. static PyObject *
  1313. _overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self,
  1314. HANDLE Pipe)
  1315. /*[clinic end generated code: output=3e69adfe55818abe input=8b0d4cef8a72f7bc]*/
  1316. {
  1317. BOOL ret;
  1318. DWORD err;
  1319. if (self->type != TYPE_NONE) {
  1320. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1321. return NULL;
  1322. }
  1323. self->type = TYPE_CONNECT_NAMED_PIPE;
  1324. self->handle = Pipe;
  1325. Py_BEGIN_ALLOW_THREADS
  1326. ret = ConnectNamedPipe(Pipe, &self->overlapped);
  1327. Py_END_ALLOW_THREADS
  1328. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  1329. switch (err) {
  1330. case ERROR_PIPE_CONNECTED:
  1331. mark_as_completed(&self->overlapped);
  1332. Py_RETURN_TRUE;
  1333. case ERROR_SUCCESS:
  1334. case ERROR_IO_PENDING:
  1335. Py_RETURN_FALSE;
  1336. default:
  1337. Overlapped_clear(self);
  1338. return SetFromWindowsErr(err);
  1339. }
  1340. }
  1341. /*[clinic input]
  1342. _overlapped.Overlapped.ConnectPipe
  1343. addr as Address: Py_UNICODE
  1344. /
  1345. Connect to the pipe for asynchronous I/O (overlapped).
  1346. [clinic start generated code]*/
  1347. static PyObject *
  1348. _overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self,
  1349. const Py_UNICODE *Address)
  1350. /*[clinic end generated code: output=3cc9661667d459d4 input=167c06a274efcefc]*/
  1351. {
  1352. HANDLE PipeHandle;
  1353. Py_BEGIN_ALLOW_THREADS
  1354. PipeHandle = CreateFileW(Address,
  1355. GENERIC_READ | GENERIC_WRITE,
  1356. 0, NULL, OPEN_EXISTING,
  1357. FILE_FLAG_OVERLAPPED, NULL);
  1358. Py_END_ALLOW_THREADS
  1359. if (PipeHandle == INVALID_HANDLE_VALUE)
  1360. return SetFromWindowsErr(0);
  1361. return Py_BuildValue(F_HANDLE, PipeHandle);
  1362. }
  1363. static PyObject*
  1364. Overlapped_getaddress(OverlappedObject *self)
  1365. {
  1366. return PyLong_FromVoidPtr(&self->overlapped);
  1367. }
  1368. static PyObject*
  1369. Overlapped_getpending(OverlappedObject *self)
  1370. {
  1371. return PyBool_FromLong(!HasOverlappedIoCompleted(&self->overlapped) &&
  1372. self->type != TYPE_NOT_STARTED);
  1373. }
  1374. static int
  1375. Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
  1376. {
  1377. switch (self->type) {
  1378. case TYPE_READ:
  1379. case TYPE_ACCEPT:
  1380. Py_VISIT(self->allocated_buffer);
  1381. break;
  1382. case TYPE_WRITE:
  1383. case TYPE_WRITE_TO:
  1384. case TYPE_READINTO:
  1385. if (self->user_buffer.obj) {
  1386. Py_VISIT(&self->user_buffer.obj);
  1387. }
  1388. break;
  1389. case TYPE_READ_FROM:
  1390. Py_VISIT(self->read_from.result);
  1391. Py_VISIT(self->read_from.allocated_buffer);
  1392. break;
  1393. case TYPE_READ_FROM_INTO:
  1394. Py_VISIT(self->read_from_into.result);
  1395. if (self->read_from_into.user_buffer.obj) {
  1396. Py_VISIT(&self->read_from_into.user_buffer.obj);
  1397. }
  1398. break;
  1399. }
  1400. return 0;
  1401. }
  1402. // UDP functions
  1403. /*
  1404. * Note: WSAConnect does not support Overlapped I/O so this function should
  1405. * _only_ be used for connectionless sockets (UDP).
  1406. */
  1407. /*[clinic input]
  1408. _overlapped.WSAConnect
  1409. client_handle as ConnectSocket: HANDLE
  1410. address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
  1411. /
  1412. Bind a remote address to a connectionless (UDP) socket.
  1413. [clinic start generated code]*/
  1414. static PyObject *
  1415. _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket,
  1416. PyObject *AddressObj)
  1417. /*[clinic end generated code: output=ea0b4391e94dad63 input=7cf65313d49c015a]*/
  1418. {
  1419. char AddressBuf[sizeof(struct sockaddr_in6)];
  1420. SOCKADDR *Address = (SOCKADDR*)AddressBuf;
  1421. int Length;
  1422. int err;
  1423. Length = sizeof(AddressBuf);
  1424. Length = parse_address(AddressObj, Address, Length);
  1425. if (Length < 0) {
  1426. return NULL;
  1427. }
  1428. Py_BEGIN_ALLOW_THREADS
  1429. // WSAConnect does not support overlapped I/O so this call will
  1430. // successfully complete immediately.
  1431. err = WSAConnect((SOCKET)ConnectSocket, Address, Length,
  1432. NULL, NULL, NULL, NULL);
  1433. Py_END_ALLOW_THREADS
  1434. if (err == 0) {
  1435. Py_RETURN_NONE;
  1436. }
  1437. else {
  1438. return SetFromWindowsErr(WSAGetLastError());
  1439. }
  1440. }
  1441. /*[clinic input]
  1442. _overlapped.Overlapped.WSASendTo
  1443. handle: HANDLE
  1444. buf as bufobj: Py_buffer
  1445. flags: DWORD
  1446. address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
  1447. /
  1448. Start overlapped sendto over a connectionless (UDP) socket.
  1449. [clinic start generated code]*/
  1450. static PyObject *
  1451. _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
  1452. Py_buffer *bufobj, DWORD flags,
  1453. PyObject *AddressObj)
  1454. /*[clinic end generated code: output=3cdedc4cfaeb70cd input=31f44cd4ab92fc33]*/
  1455. {
  1456. char AddressBuf[sizeof(struct sockaddr_in6)];
  1457. SOCKADDR *Address = (SOCKADDR*)AddressBuf;
  1458. int AddressLength;
  1459. DWORD written;
  1460. WSABUF wsabuf;
  1461. int ret;
  1462. DWORD err;
  1463. // Parse the "to" address
  1464. AddressLength = sizeof(AddressBuf);
  1465. AddressLength = parse_address(AddressObj, Address, AddressLength);
  1466. if (AddressLength < 0) {
  1467. return NULL;
  1468. }
  1469. if (self->type != TYPE_NONE) {
  1470. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1471. return NULL;
  1472. }
  1473. #if SIZEOF_SIZE_T > SIZEOF_LONG
  1474. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  1475. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1476. return NULL;
  1477. }
  1478. #endif
  1479. steal_buffer(&self->user_buffer, bufobj);
  1480. self->type = TYPE_WRITE_TO;
  1481. self->handle = handle;
  1482. wsabuf.len = (DWORD)self->user_buffer.len;
  1483. wsabuf.buf = self->user_buffer.buf;
  1484. Py_BEGIN_ALLOW_THREADS
  1485. ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags,
  1486. Address, AddressLength, &self->overlapped, NULL);
  1487. Py_END_ALLOW_THREADS
  1488. self->error = err = (ret == SOCKET_ERROR ? WSAGetLastError() :
  1489. ERROR_SUCCESS);
  1490. switch(err) {
  1491. case ERROR_SUCCESS:
  1492. case ERROR_IO_PENDING:
  1493. Py_RETURN_NONE;
  1494. default:
  1495. self->type = TYPE_NOT_STARTED;
  1496. return SetFromWindowsErr(err);
  1497. }
  1498. }
  1499. PyDoc_STRVAR(
  1500. Overlapped_WSARecvFrom_doc,
  1501. "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n"
  1502. "Start overlapped receive");
  1503. /*[clinic input]
  1504. _overlapped.Overlapped.WSARecvFrom
  1505. handle: HANDLE
  1506. size: DWORD
  1507. flags: DWORD = 0
  1508. /
  1509. Start overlapped receive.
  1510. [clinic start generated code]*/
  1511. static PyObject *
  1512. _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self,
  1513. HANDLE handle, DWORD size,
  1514. DWORD flags)
  1515. /*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/
  1516. {
  1517. PyObject *buf;
  1518. DWORD nread;
  1519. WSABUF wsabuf;
  1520. int ret;
  1521. DWORD err;
  1522. if (self->type != TYPE_NONE) {
  1523. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1524. return NULL;
  1525. }
  1526. #if SIZEOF_SIZE_T <= SIZEOF_LONG
  1527. size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
  1528. #endif
  1529. buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
  1530. if (buf == NULL) {
  1531. return NULL;
  1532. }
  1533. wsabuf.buf = PyBytes_AS_STRING(buf);
  1534. wsabuf.len = size;
  1535. self->type = TYPE_READ_FROM;
  1536. self->handle = handle;
  1537. self->read_from.allocated_buffer = buf;
  1538. memset(&self->read_from.address, 0, sizeof(self->read_from.address));
  1539. self->read_from.address_length = sizeof(self->read_from.address);
  1540. Py_BEGIN_ALLOW_THREADS
  1541. ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
  1542. (SOCKADDR*)&self->read_from.address,
  1543. &self->read_from.address_length,
  1544. &self->overlapped, NULL);
  1545. Py_END_ALLOW_THREADS
  1546. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  1547. switch (err) {
  1548. case ERROR_BROKEN_PIPE:
  1549. mark_as_completed(&self->overlapped);
  1550. return SetFromWindowsErr(err);
  1551. case ERROR_SUCCESS:
  1552. case ERROR_MORE_DATA:
  1553. case ERROR_IO_PENDING:
  1554. Py_RETURN_NONE;
  1555. default:
  1556. self->type = TYPE_NOT_STARTED;
  1557. return SetFromWindowsErr(err);
  1558. }
  1559. }
  1560. /*[clinic input]
  1561. _overlapped.Overlapped.WSARecvFromInto
  1562. handle: HANDLE
  1563. buf as bufobj: Py_buffer
  1564. size: DWORD
  1565. flags: DWORD = 0
  1566. /
  1567. Start overlapped receive.
  1568. [clinic start generated code]*/
  1569. static PyObject *
  1570. _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self,
  1571. HANDLE handle, Py_buffer *bufobj,
  1572. DWORD size, DWORD flags)
  1573. /*[clinic end generated code: output=30c7ea171a691757 input=4be4b08d03531e76]*/
  1574. {
  1575. DWORD nread;
  1576. WSABUF wsabuf;
  1577. int ret;
  1578. DWORD err;
  1579. if (self->type != TYPE_NONE) {
  1580. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1581. return NULL;
  1582. }
  1583. #if SIZEOF_SIZE_T > SIZEOF_LONG
  1584. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  1585. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1586. return NULL;
  1587. }
  1588. #endif
  1589. wsabuf.buf = bufobj->buf;
  1590. wsabuf.len = size;
  1591. self->type = TYPE_READ_FROM_INTO;
  1592. self->handle = handle;
  1593. steal_buffer(&self->read_from_into.user_buffer, bufobj);
  1594. memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address));
  1595. self->read_from_into.address_length = sizeof(self->read_from_into.address);
  1596. Py_BEGIN_ALLOW_THREADS
  1597. ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
  1598. (SOCKADDR*)&self->read_from_into.address,
  1599. &self->read_from_into.address_length,
  1600. &self->overlapped, NULL);
  1601. Py_END_ALLOW_THREADS
  1602. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  1603. switch (err) {
  1604. case ERROR_BROKEN_PIPE:
  1605. mark_as_completed(&self->overlapped);
  1606. return SetFromWindowsErr(err);
  1607. case ERROR_SUCCESS:
  1608. case ERROR_MORE_DATA:
  1609. case ERROR_IO_PENDING:
  1610. Py_RETURN_NONE;
  1611. default:
  1612. self->type = TYPE_NOT_STARTED;
  1613. return SetFromWindowsErr(err);
  1614. }
  1615. }
  1616. #include "clinic/overlapped.c.h"
  1617. static PyMethodDef Overlapped_methods[] = {
  1618. _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF
  1619. _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF
  1620. _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF
  1621. _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF
  1622. _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF
  1623. _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF
  1624. _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
  1625. _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF
  1626. _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF
  1627. _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF
  1628. _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF
  1629. _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF
  1630. _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF
  1631. _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF
  1632. _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF
  1633. _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
  1634. _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF
  1635. {NULL}
  1636. };
  1637. static PyMemberDef Overlapped_members[] = {
  1638. {"error", T_ULONG,
  1639. offsetof(OverlappedObject, error),
  1640. READONLY, "Error from last operation"},
  1641. {"event", T_HANDLE,
  1642. offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
  1643. READONLY, "Overlapped event handle"},
  1644. {NULL}
  1645. };
  1646. static PyGetSetDef Overlapped_getsets[] = {
  1647. {"address", (getter)Overlapped_getaddress, NULL,
  1648. "Address of overlapped structure"},
  1649. {"pending", (getter)Overlapped_getpending, NULL,
  1650. "Whether the operation is pending"},
  1651. {NULL},
  1652. };
  1653. static PyType_Slot overlapped_type_slots[] = {
  1654. {Py_tp_dealloc, Overlapped_dealloc},
  1655. {Py_tp_doc, (char *)_overlapped_Overlapped__doc__},
  1656. {Py_tp_traverse, Overlapped_traverse},
  1657. {Py_tp_methods, Overlapped_methods},
  1658. {Py_tp_members, Overlapped_members},
  1659. {Py_tp_getset, Overlapped_getsets},
  1660. {Py_tp_new, _overlapped_Overlapped},
  1661. {0,0}
  1662. };
  1663. static PyType_Spec overlapped_type_spec = {
  1664. .name = "_overlapped.Overlapped",
  1665. .basicsize = sizeof(OverlappedObject),
  1666. .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
  1667. .slots = overlapped_type_slots
  1668. };
  1669. static PyMethodDef overlapped_functions[] = {
  1670. _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF
  1671. _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF
  1672. _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF
  1673. _OVERLAPPED_FORMATMESSAGE_METHODDEF
  1674. _OVERLAPPED_BINDLOCAL_METHODDEF
  1675. _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF
  1676. _OVERLAPPED_UNREGISTERWAIT_METHODDEF
  1677. _OVERLAPPED_UNREGISTERWAITEX_METHODDEF
  1678. _OVERLAPPED_CREATEEVENT_METHODDEF
  1679. _OVERLAPPED_SETEVENT_METHODDEF
  1680. _OVERLAPPED_RESETEVENT_METHODDEF
  1681. _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF
  1682. _OVERLAPPED_WSACONNECT_METHODDEF
  1683. {NULL}
  1684. };
  1685. #define WINAPI_CONSTANT(fmt, con) \
  1686. do { \
  1687. PyObject *value = Py_BuildValue(fmt, con); \
  1688. if (value == NULL) { \
  1689. return -1; \
  1690. } \
  1691. if (PyModule_AddObject(module, #con, value) < 0 ) { \
  1692. Py_DECREF(value); \
  1693. return -1; \
  1694. } \
  1695. } while (0)
  1696. static int
  1697. overlapped_exec(PyObject *module)
  1698. {
  1699. /* Ensure WSAStartup() called before initializing function pointers */
  1700. PyObject *socket_module = PyImport_ImportModule("_socket");
  1701. if (!socket_module) {
  1702. return -1;
  1703. }
  1704. Py_DECREF(socket_module);
  1705. if (initialize_function_pointers() < 0) {
  1706. return -1;
  1707. }
  1708. PyTypeObject *overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(
  1709. module, &overlapped_type_spec, NULL);
  1710. if (overlapped_type == NULL) {
  1711. return -1;
  1712. }
  1713. int rc = PyModule_AddType(module, overlapped_type);
  1714. Py_DECREF(overlapped_type);
  1715. if (rc < 0) {
  1716. return -1;
  1717. }
  1718. WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
  1719. WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
  1720. WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED);
  1721. WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
  1722. WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
  1723. WINAPI_CONSTANT(F_DWORD, ERROR_PORT_UNREACHABLE);
  1724. WINAPI_CONSTANT(F_DWORD, INFINITE);
  1725. WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE);
  1726. WINAPI_CONSTANT(F_HANDLE, NULL);
  1727. WINAPI_CONSTANT(F_DWORD, SO_UPDATE_ACCEPT_CONTEXT);
  1728. WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT);
  1729. WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET);
  1730. return 0;
  1731. }
  1732. static PyModuleDef_Slot overlapped_slots[] = {
  1733. {Py_mod_exec, overlapped_exec},
  1734. {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
  1735. {0, NULL}
  1736. };
  1737. static struct PyModuleDef overlapped_module = {
  1738. .m_base = PyModuleDef_HEAD_INIT,
  1739. .m_name = "_overlapped",
  1740. .m_methods = overlapped_functions,
  1741. .m_slots = overlapped_slots,
  1742. };
  1743. PyMODINIT_FUNC
  1744. PyInit__overlapped(void)
  1745. {
  1746. return PyModuleDef_Init(&overlapped_module);
  1747. }