overlapped.c 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069
  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. Py_BEGIN_ALLOW_THREADS
  596. if (CancelIoEx(self->handle, &self->overlapped))
  597. wait = TRUE;
  598. ret = GetOverlappedResult(self->handle, &self->overlapped,
  599. &bytes, wait);
  600. Py_END_ALLOW_THREADS
  601. switch (ret ? ERROR_SUCCESS : GetLastError()) {
  602. case ERROR_SUCCESS:
  603. case ERROR_NOT_FOUND:
  604. case ERROR_OPERATION_ABORTED:
  605. break;
  606. default:
  607. PyErr_Format(
  608. PyExc_RuntimeError,
  609. "%R still has pending operation at "
  610. "deallocation, the process may crash", self);
  611. PyErr_WriteUnraisable(NULL);
  612. }
  613. }
  614. if (self->overlapped.hEvent != NULL) {
  615. CloseHandle(self->overlapped.hEvent);
  616. }
  617. Overlapped_clear(self);
  618. SetLastError(olderr);
  619. PyTypeObject *tp = Py_TYPE(self);
  620. PyObject_Free(self);
  621. Py_DECREF(tp);
  622. }
  623. /* Convert IPv4 sockaddr to a Python str. */
  624. static PyObject *
  625. make_ipv4_addr(const struct sockaddr_in *addr)
  626. {
  627. char buf[INET_ADDRSTRLEN];
  628. if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) {
  629. PyErr_SetFromErrno(PyExc_OSError);
  630. return NULL;
  631. }
  632. return PyUnicode_FromString(buf);
  633. }
  634. /* Convert IPv6 sockaddr to a Python str. */
  635. static PyObject *
  636. make_ipv6_addr(const struct sockaddr_in6 *addr)
  637. {
  638. char buf[INET6_ADDRSTRLEN];
  639. if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) {
  640. PyErr_SetFromErrno(PyExc_OSError);
  641. return NULL;
  642. }
  643. return PyUnicode_FromString(buf);
  644. }
  645. static PyObject*
  646. unparse_address(LPSOCKADDR Address, DWORD Length)
  647. {
  648. /* The function is adopted from mocketmodule.c makesockaddr()*/
  649. switch(Address->sa_family) {
  650. case AF_INET: {
  651. const struct sockaddr_in *a = (const struct sockaddr_in *)Address;
  652. PyObject *addrobj = make_ipv4_addr(a);
  653. PyObject *ret = NULL;
  654. if (addrobj) {
  655. ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
  656. Py_DECREF(addrobj);
  657. }
  658. return ret;
  659. }
  660. case AF_INET6: {
  661. const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)Address;
  662. PyObject *addrobj = make_ipv6_addr(a);
  663. PyObject *ret = NULL;
  664. if (addrobj) {
  665. ret = Py_BuildValue("OiII",
  666. addrobj,
  667. ntohs(a->sin6_port),
  668. ntohl(a->sin6_flowinfo),
  669. a->sin6_scope_id);
  670. Py_DECREF(addrobj);
  671. }
  672. return ret;
  673. }
  674. default: {
  675. PyErr_SetString(PyExc_ValueError, "recvfrom returned unsupported address family");
  676. return NULL;
  677. }
  678. }
  679. }
  680. /*[clinic input]
  681. _overlapped.Overlapped.cancel
  682. Cancel overlapped operation.
  683. [clinic start generated code]*/
  684. static PyObject *
  685. _overlapped_Overlapped_cancel_impl(OverlappedObject *self)
  686. /*[clinic end generated code: output=54ad7aeece89901c input=80eb67c7b57dbcf1]*/
  687. {
  688. BOOL ret = TRUE;
  689. if (self->type == TYPE_NOT_STARTED
  690. || self->type == TYPE_WAIT_NAMED_PIPE_AND_CONNECT)
  691. Py_RETURN_NONE;
  692. if (!HasOverlappedIoCompleted(&self->overlapped)) {
  693. Py_BEGIN_ALLOW_THREADS
  694. ret = CancelIoEx(self->handle, &self->overlapped);
  695. Py_END_ALLOW_THREADS
  696. }
  697. /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */
  698. if (!ret && GetLastError() != ERROR_NOT_FOUND)
  699. return SetFromWindowsErr(0);
  700. Py_RETURN_NONE;
  701. }
  702. /*[clinic input]
  703. _overlapped.Overlapped.getresult
  704. wait: BOOL(c_default='FALSE') = False
  705. /
  706. Retrieve result of operation.
  707. If wait is true then it blocks until the operation is finished. If wait
  708. is false and the operation is still pending then an error is raised.
  709. [clinic start generated code]*/
  710. static PyObject *
  711. _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait)
  712. /*[clinic end generated code: output=8c9bd04d08994f6c input=aa5b03e9897ca074]*/
  713. {
  714. DWORD transferred = 0;
  715. BOOL ret;
  716. DWORD err;
  717. PyObject *addr;
  718. if (self->type == TYPE_NONE) {
  719. PyErr_SetString(PyExc_ValueError, "operation not yet attempted");
  720. return NULL;
  721. }
  722. if (self->type == TYPE_NOT_STARTED) {
  723. PyErr_SetString(PyExc_ValueError, "operation failed to start");
  724. return NULL;
  725. }
  726. Py_BEGIN_ALLOW_THREADS
  727. ret = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
  728. wait);
  729. Py_END_ALLOW_THREADS
  730. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  731. switch (err) {
  732. case ERROR_SUCCESS:
  733. case ERROR_MORE_DATA:
  734. break;
  735. case ERROR_BROKEN_PIPE:
  736. if (self->type == TYPE_READ || self->type == TYPE_READINTO) {
  737. break;
  738. }
  739. else if (self->type == TYPE_READ_FROM &&
  740. (self->read_from.result != NULL ||
  741. self->read_from.allocated_buffer != NULL))
  742. {
  743. break;
  744. }
  745. else if (self->type == TYPE_READ_FROM_INTO &&
  746. self->read_from_into.result != NULL)
  747. {
  748. break;
  749. }
  750. /* fall through */
  751. default:
  752. return SetFromWindowsErr(err);
  753. }
  754. switch (self->type) {
  755. case TYPE_READ:
  756. assert(PyBytes_CheckExact(self->allocated_buffer));
  757. if (transferred != PyBytes_GET_SIZE(self->allocated_buffer) &&
  758. _PyBytes_Resize(&self->allocated_buffer, transferred))
  759. return NULL;
  760. return Py_NewRef(self->allocated_buffer);
  761. case TYPE_READ_FROM:
  762. assert(PyBytes_CheckExact(self->read_from.allocated_buffer));
  763. if (transferred != PyBytes_GET_SIZE(
  764. self->read_from.allocated_buffer) &&
  765. _PyBytes_Resize(&self->read_from.allocated_buffer, transferred))
  766. {
  767. return NULL;
  768. }
  769. // unparse the address
  770. addr = unparse_address((SOCKADDR*)&self->read_from.address,
  771. self->read_from.address_length);
  772. if (addr == NULL) {
  773. return NULL;
  774. }
  775. // The result is a two item tuple: (message, address)
  776. self->read_from.result = PyTuple_New(2);
  777. if (self->read_from.result == NULL) {
  778. Py_CLEAR(addr);
  779. return NULL;
  780. }
  781. // first item: message
  782. PyTuple_SET_ITEM(self->read_from.result, 0,
  783. Py_NewRef(self->read_from.allocated_buffer));
  784. // second item: address
  785. PyTuple_SET_ITEM(self->read_from.result, 1, addr);
  786. return Py_NewRef(self->read_from.result);
  787. case TYPE_READ_FROM_INTO:
  788. // unparse the address
  789. addr = unparse_address((SOCKADDR*)&self->read_from_into.address,
  790. self->read_from_into.address_length);
  791. if (addr == NULL) {
  792. return NULL;
  793. }
  794. // The result is a two item tuple: (number of bytes read, address)
  795. self->read_from_into.result = PyTuple_New(2);
  796. if (self->read_from_into.result == NULL) {
  797. Py_CLEAR(addr);
  798. return NULL;
  799. }
  800. // first item: number of bytes read
  801. PyTuple_SET_ITEM(self->read_from_into.result, 0,
  802. PyLong_FromUnsignedLong((unsigned long)transferred));
  803. // second item: address
  804. PyTuple_SET_ITEM(self->read_from_into.result, 1, addr);
  805. return Py_NewRef(self->read_from_into.result);
  806. default:
  807. return PyLong_FromUnsignedLong((unsigned long) transferred);
  808. }
  809. }
  810. static PyObject *
  811. do_ReadFile(OverlappedObject *self, HANDLE handle,
  812. char *bufstart, DWORD buflen)
  813. {
  814. DWORD nread;
  815. int ret;
  816. DWORD err;
  817. Py_BEGIN_ALLOW_THREADS
  818. ret = ReadFile(handle, bufstart, buflen, &nread,
  819. &self->overlapped);
  820. Py_END_ALLOW_THREADS
  821. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  822. switch (err) {
  823. case ERROR_BROKEN_PIPE:
  824. mark_as_completed(&self->overlapped);
  825. return SetFromWindowsErr(err);
  826. case ERROR_SUCCESS:
  827. case ERROR_MORE_DATA:
  828. case ERROR_IO_PENDING:
  829. Py_RETURN_NONE;
  830. default:
  831. Overlapped_clear(self);
  832. return SetFromWindowsErr(err);
  833. }
  834. }
  835. /*[clinic input]
  836. _overlapped.Overlapped.ReadFile
  837. handle: HANDLE
  838. size: DWORD
  839. /
  840. Start overlapped read.
  841. [clinic start generated code]*/
  842. static PyObject *
  843. _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle,
  844. DWORD size)
  845. /*[clinic end generated code: output=4c8557e16941e4ae input=98c495baa0342425]*/
  846. {
  847. PyObject *buf;
  848. if (self->type != TYPE_NONE) {
  849. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  850. return NULL;
  851. }
  852. #if SIZEOF_SIZE_T <= SIZEOF_LONG
  853. size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
  854. #endif
  855. buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
  856. if (buf == NULL)
  857. return NULL;
  858. self->type = TYPE_READ;
  859. self->handle = handle;
  860. self->allocated_buffer = buf;
  861. return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size);
  862. }
  863. /*[clinic input]
  864. _overlapped.Overlapped.ReadFileInto
  865. handle: HANDLE
  866. buf as bufobj: Py_buffer
  867. /
  868. Start overlapped receive.
  869. [clinic start generated code]*/
  870. static PyObject *
  871. _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self,
  872. HANDLE handle, Py_buffer *bufobj)
  873. /*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/
  874. {
  875. if (self->type != TYPE_NONE) {
  876. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  877. return NULL;
  878. }
  879. #if SIZEOF_SIZE_T > SIZEOF_LONG
  880. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  881. PyErr_SetString(PyExc_ValueError, "buffer too large");
  882. return NULL;
  883. }
  884. #endif
  885. steal_buffer(&self->user_buffer, bufobj);
  886. self->type = TYPE_READINTO;
  887. self->handle = handle;
  888. return do_ReadFile(self, handle, self->user_buffer.buf,
  889. (DWORD)self->user_buffer.len);
  890. }
  891. static PyObject *
  892. do_WSARecv(OverlappedObject *self, HANDLE handle,
  893. char *bufstart, DWORD buflen, DWORD flags)
  894. {
  895. DWORD nread;
  896. WSABUF wsabuf;
  897. int ret;
  898. DWORD err;
  899. wsabuf.buf = bufstart;
  900. wsabuf.len = buflen;
  901. Py_BEGIN_ALLOW_THREADS
  902. ret = WSARecv((SOCKET)handle, &wsabuf, 1, &nread, &flags,
  903. &self->overlapped, NULL);
  904. Py_END_ALLOW_THREADS
  905. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  906. switch (err) {
  907. case ERROR_BROKEN_PIPE:
  908. mark_as_completed(&self->overlapped);
  909. return SetFromWindowsErr(err);
  910. case ERROR_SUCCESS:
  911. case ERROR_MORE_DATA:
  912. case ERROR_IO_PENDING:
  913. Py_RETURN_NONE;
  914. default:
  915. Overlapped_clear(self);
  916. return SetFromWindowsErr(err);
  917. }
  918. }
  919. /*[clinic input]
  920. _overlapped.Overlapped.WSARecv
  921. handle: HANDLE
  922. size: DWORD
  923. flags: DWORD = 0
  924. /
  925. Start overlapped receive.
  926. [clinic start generated code]*/
  927. static PyObject *
  928. _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle,
  929. DWORD size, DWORD flags)
  930. /*[clinic end generated code: output=3a5e9c61ff040906 input=8c04e506cc3d741a]*/
  931. {
  932. PyObject *buf;
  933. if (self->type != TYPE_NONE) {
  934. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  935. return NULL;
  936. }
  937. #if SIZEOF_SIZE_T <= SIZEOF_LONG
  938. size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
  939. #endif
  940. buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
  941. if (buf == NULL)
  942. return NULL;
  943. self->type = TYPE_READ;
  944. self->handle = handle;
  945. self->allocated_buffer = buf;
  946. return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags);
  947. }
  948. /*[clinic input]
  949. _overlapped.Overlapped.WSARecvInto
  950. handle: HANDLE
  951. buf as bufobj: Py_buffer
  952. flags: DWORD
  953. /
  954. Start overlapped receive.
  955. [clinic start generated code]*/
  956. static PyObject *
  957. _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
  958. HANDLE handle, Py_buffer *bufobj,
  959. DWORD flags)
  960. /*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/
  961. {
  962. if (self->type != TYPE_NONE) {
  963. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  964. return NULL;
  965. }
  966. #if SIZEOF_SIZE_T > SIZEOF_LONG
  967. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  968. PyErr_SetString(PyExc_ValueError, "buffer too large");
  969. return NULL;
  970. }
  971. #endif
  972. steal_buffer(&self->user_buffer, bufobj);
  973. self->type = TYPE_READINTO;
  974. self->handle = handle;
  975. return do_WSARecv(self, handle, self->user_buffer.buf,
  976. (DWORD)self->user_buffer.len, flags);
  977. }
  978. /*[clinic input]
  979. _overlapped.Overlapped.WriteFile
  980. handle: HANDLE
  981. buf as bufobj: Py_buffer
  982. /
  983. Start overlapped write.
  984. [clinic start generated code]*/
  985. static PyObject *
  986. _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
  987. Py_buffer *bufobj)
  988. /*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/
  989. {
  990. DWORD written;
  991. BOOL ret;
  992. DWORD err;
  993. if (self->type != TYPE_NONE) {
  994. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  995. return NULL;
  996. }
  997. #if SIZEOF_SIZE_T > SIZEOF_LONG
  998. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  999. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1000. return NULL;
  1001. }
  1002. #endif
  1003. steal_buffer(&self->user_buffer, bufobj);
  1004. self->type = TYPE_WRITE;
  1005. self->handle = handle;
  1006. Py_BEGIN_ALLOW_THREADS
  1007. ret = WriteFile(handle, self->user_buffer.buf,
  1008. (DWORD)self->user_buffer.len,
  1009. &written, &self->overlapped);
  1010. Py_END_ALLOW_THREADS
  1011. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  1012. switch (err) {
  1013. case ERROR_SUCCESS:
  1014. case ERROR_IO_PENDING:
  1015. Py_RETURN_NONE;
  1016. default:
  1017. Overlapped_clear(self);
  1018. return SetFromWindowsErr(err);
  1019. }
  1020. }
  1021. /*[clinic input]
  1022. _overlapped.Overlapped.WSASend
  1023. handle: HANDLE
  1024. buf as bufobj: Py_buffer
  1025. flags: DWORD
  1026. /
  1027. Start overlapped send.
  1028. [clinic start generated code]*/
  1029. static PyObject *
  1030. _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
  1031. Py_buffer *bufobj, DWORD flags)
  1032. /*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/
  1033. {
  1034. DWORD written;
  1035. WSABUF wsabuf;
  1036. int ret;
  1037. DWORD err;
  1038. if (self->type != TYPE_NONE) {
  1039. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1040. return NULL;
  1041. }
  1042. #if SIZEOF_SIZE_T > SIZEOF_LONG
  1043. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  1044. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1045. return NULL;
  1046. }
  1047. #endif
  1048. steal_buffer(&self->user_buffer, bufobj);
  1049. self->type = TYPE_WRITE;
  1050. self->handle = handle;
  1051. wsabuf.len = (DWORD)self->user_buffer.len;
  1052. wsabuf.buf = self->user_buffer.buf;
  1053. Py_BEGIN_ALLOW_THREADS
  1054. ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags,
  1055. &self->overlapped, NULL);
  1056. Py_END_ALLOW_THREADS
  1057. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  1058. switch (err) {
  1059. case ERROR_SUCCESS:
  1060. case ERROR_IO_PENDING:
  1061. Py_RETURN_NONE;
  1062. default:
  1063. Overlapped_clear(self);
  1064. return SetFromWindowsErr(err);
  1065. }
  1066. }
  1067. /*[clinic input]
  1068. _overlapped.Overlapped.AcceptEx
  1069. listen_handle as ListenSocket: HANDLE
  1070. accept_handle as AcceptSocket: HANDLE
  1071. /
  1072. Start overlapped wait for client to connect.
  1073. [clinic start generated code]*/
  1074. static PyObject *
  1075. _overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self,
  1076. HANDLE ListenSocket,
  1077. HANDLE AcceptSocket)
  1078. /*[clinic end generated code: output=9a7381d4232af889 input=b83473224fc3a1c5]*/
  1079. {
  1080. DWORD BytesReceived;
  1081. DWORD size;
  1082. PyObject *buf;
  1083. BOOL ret;
  1084. DWORD err;
  1085. if (self->type != TYPE_NONE) {
  1086. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1087. return NULL;
  1088. }
  1089. size = sizeof(struct sockaddr_in6) + 16;
  1090. buf = PyBytes_FromStringAndSize(NULL, size*2);
  1091. if (!buf)
  1092. return NULL;
  1093. self->type = TYPE_ACCEPT;
  1094. self->handle = ListenSocket;
  1095. self->allocated_buffer = buf;
  1096. Py_BEGIN_ALLOW_THREADS
  1097. ret = Py_AcceptEx((SOCKET)ListenSocket, (SOCKET)AcceptSocket,
  1098. PyBytes_AS_STRING(buf), 0, size, size, &BytesReceived,
  1099. &self->overlapped);
  1100. Py_END_ALLOW_THREADS
  1101. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1102. switch (err) {
  1103. case ERROR_SUCCESS:
  1104. case ERROR_IO_PENDING:
  1105. Py_RETURN_NONE;
  1106. default:
  1107. Overlapped_clear(self);
  1108. return SetFromWindowsErr(err);
  1109. }
  1110. }
  1111. static int
  1112. parse_address(PyObject *obj, SOCKADDR *Address, int Length)
  1113. {
  1114. PyObject *Host_obj;
  1115. wchar_t *Host;
  1116. unsigned short Port;
  1117. unsigned long FlowInfo;
  1118. unsigned long ScopeId;
  1119. memset(Address, 0, Length);
  1120. switch (PyTuple_GET_SIZE(obj)) {
  1121. case 2: {
  1122. if (!PyArg_ParseTuple(obj, "UH", &Host_obj, &Port)) {
  1123. return -1;
  1124. }
  1125. Host = PyUnicode_AsWideCharString(Host_obj, NULL);
  1126. if (Host == NULL) {
  1127. return -1;
  1128. }
  1129. Address->sa_family = AF_INET;
  1130. if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) {
  1131. SetFromWindowsErr(WSAGetLastError());
  1132. Length = -1;
  1133. }
  1134. else {
  1135. ((SOCKADDR_IN*)Address)->sin_port = htons(Port);
  1136. }
  1137. PyMem_Free(Host);
  1138. return Length;
  1139. }
  1140. case 4: {
  1141. if (!PyArg_ParseTuple(obj,
  1142. "UHkk;ConnectEx(): illegal address_as_bytes argument",
  1143. &Host_obj, &Port, &FlowInfo, &ScopeId))
  1144. {
  1145. return -1;
  1146. }
  1147. Host = PyUnicode_AsWideCharString(Host_obj, NULL);
  1148. if (Host == NULL) {
  1149. return -1;
  1150. }
  1151. Address->sa_family = AF_INET6;
  1152. if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) {
  1153. SetFromWindowsErr(WSAGetLastError());
  1154. Length = -1;
  1155. }
  1156. else {
  1157. ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port);
  1158. ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo;
  1159. ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId;
  1160. }
  1161. PyMem_Free(Host);
  1162. return Length;
  1163. }
  1164. default:
  1165. PyErr_SetString(PyExc_ValueError, "illegal address_as_bytes argument");
  1166. return -1;
  1167. }
  1168. }
  1169. /*[clinic input]
  1170. _overlapped.Overlapped.ConnectEx
  1171. client_handle as ConnectSocket: HANDLE
  1172. address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
  1173. /
  1174. Start overlapped connect.
  1175. client_handle should be unbound.
  1176. [clinic start generated code]*/
  1177. static PyObject *
  1178. _overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self,
  1179. HANDLE ConnectSocket,
  1180. PyObject *AddressObj)
  1181. /*[clinic end generated code: output=5aebbbdb4f022833 input=d6bbd2d84b156fc1]*/
  1182. {
  1183. char AddressBuf[sizeof(struct sockaddr_in6)];
  1184. SOCKADDR *Address = (SOCKADDR*)AddressBuf;
  1185. int Length;
  1186. BOOL ret;
  1187. DWORD err;
  1188. if (self->type != TYPE_NONE) {
  1189. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1190. return NULL;
  1191. }
  1192. Length = sizeof(AddressBuf);
  1193. Length = parse_address(AddressObj, Address, Length);
  1194. if (Length < 0)
  1195. return NULL;
  1196. self->type = TYPE_CONNECT;
  1197. self->handle = ConnectSocket;
  1198. Py_BEGIN_ALLOW_THREADS
  1199. ret = Py_ConnectEx((SOCKET)ConnectSocket, Address, Length,
  1200. NULL, 0, NULL, &self->overlapped);
  1201. Py_END_ALLOW_THREADS
  1202. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1203. switch (err) {
  1204. case ERROR_SUCCESS:
  1205. case ERROR_IO_PENDING:
  1206. Py_RETURN_NONE;
  1207. default:
  1208. Overlapped_clear(self);
  1209. return SetFromWindowsErr(err);
  1210. }
  1211. }
  1212. /*[clinic input]
  1213. _overlapped.Overlapped.DisconnectEx
  1214. handle as Socket: HANDLE
  1215. flags: DWORD
  1216. /
  1217. [clinic start generated code]*/
  1218. static PyObject *
  1219. _overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self,
  1220. HANDLE Socket, DWORD flags)
  1221. /*[clinic end generated code: output=8d64ddb8c93c2126 input=680845cdcdf820eb]*/
  1222. {
  1223. BOOL ret;
  1224. DWORD err;
  1225. if (self->type != TYPE_NONE) {
  1226. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1227. return NULL;
  1228. }
  1229. self->type = TYPE_DISCONNECT;
  1230. self->handle = Socket;
  1231. Py_BEGIN_ALLOW_THREADS
  1232. ret = Py_DisconnectEx((SOCKET)Socket, &self->overlapped, flags, 0);
  1233. Py_END_ALLOW_THREADS
  1234. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1235. switch (err) {
  1236. case ERROR_SUCCESS:
  1237. case ERROR_IO_PENDING:
  1238. Py_RETURN_NONE;
  1239. default:
  1240. Overlapped_clear(self);
  1241. return SetFromWindowsErr(err);
  1242. }
  1243. }
  1244. /*[clinic input]
  1245. _overlapped.Overlapped.TransmitFile
  1246. socket as Socket: HANDLE
  1247. file as File: HANDLE
  1248. offset: DWORD
  1249. offset_high: DWORD
  1250. count_to_write: DWORD
  1251. count_per_send: DWORD
  1252. flags: DWORD
  1253. /
  1254. Transmit file data over a connected socket.
  1255. [clinic start generated code]*/
  1256. static PyObject *
  1257. _overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self,
  1258. HANDLE Socket, HANDLE File,
  1259. DWORD offset, DWORD offset_high,
  1260. DWORD count_to_write,
  1261. DWORD count_per_send, DWORD flags)
  1262. /*[clinic end generated code: output=03f3ca5512e678fd input=7e6f97b391f60e8c]*/
  1263. {
  1264. BOOL ret;
  1265. DWORD err;
  1266. if (self->type != TYPE_NONE) {
  1267. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1268. return NULL;
  1269. }
  1270. self->type = TYPE_TRANSMIT_FILE;
  1271. self->handle = Socket;
  1272. self->overlapped.Offset = offset;
  1273. self->overlapped.OffsetHigh = offset_high;
  1274. Py_BEGIN_ALLOW_THREADS
  1275. ret = Py_TransmitFile((SOCKET)Socket, File, count_to_write,
  1276. count_per_send, &self->overlapped, NULL, flags);
  1277. Py_END_ALLOW_THREADS
  1278. self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError();
  1279. switch (err) {
  1280. case ERROR_SUCCESS:
  1281. case ERROR_IO_PENDING:
  1282. Py_RETURN_NONE;
  1283. default:
  1284. Overlapped_clear(self);
  1285. return SetFromWindowsErr(err);
  1286. }
  1287. }
  1288. /*[clinic input]
  1289. _overlapped.Overlapped.ConnectNamedPipe
  1290. handle as Pipe: HANDLE
  1291. /
  1292. Start overlapped wait for a client to connect.
  1293. [clinic start generated code]*/
  1294. static PyObject *
  1295. _overlapped_Overlapped_ConnectNamedPipe_impl(OverlappedObject *self,
  1296. HANDLE Pipe)
  1297. /*[clinic end generated code: output=3e69adfe55818abe input=8b0d4cef8a72f7bc]*/
  1298. {
  1299. BOOL ret;
  1300. DWORD err;
  1301. if (self->type != TYPE_NONE) {
  1302. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1303. return NULL;
  1304. }
  1305. self->type = TYPE_CONNECT_NAMED_PIPE;
  1306. self->handle = Pipe;
  1307. Py_BEGIN_ALLOW_THREADS
  1308. ret = ConnectNamedPipe(Pipe, &self->overlapped);
  1309. Py_END_ALLOW_THREADS
  1310. self->error = err = ret ? ERROR_SUCCESS : GetLastError();
  1311. switch (err) {
  1312. case ERROR_PIPE_CONNECTED:
  1313. mark_as_completed(&self->overlapped);
  1314. Py_RETURN_TRUE;
  1315. case ERROR_SUCCESS:
  1316. case ERROR_IO_PENDING:
  1317. Py_RETURN_FALSE;
  1318. default:
  1319. Overlapped_clear(self);
  1320. return SetFromWindowsErr(err);
  1321. }
  1322. }
  1323. /*[clinic input]
  1324. _overlapped.Overlapped.ConnectPipe
  1325. addr as Address: Py_UNICODE
  1326. /
  1327. Connect to the pipe for asynchronous I/O (overlapped).
  1328. [clinic start generated code]*/
  1329. static PyObject *
  1330. _overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self,
  1331. const Py_UNICODE *Address)
  1332. /*[clinic end generated code: output=3cc9661667d459d4 input=167c06a274efcefc]*/
  1333. {
  1334. HANDLE PipeHandle;
  1335. Py_BEGIN_ALLOW_THREADS
  1336. PipeHandle = CreateFileW(Address,
  1337. GENERIC_READ | GENERIC_WRITE,
  1338. 0, NULL, OPEN_EXISTING,
  1339. FILE_FLAG_OVERLAPPED, NULL);
  1340. Py_END_ALLOW_THREADS
  1341. if (PipeHandle == INVALID_HANDLE_VALUE)
  1342. return SetFromWindowsErr(0);
  1343. return Py_BuildValue(F_HANDLE, PipeHandle);
  1344. }
  1345. static PyObject*
  1346. Overlapped_getaddress(OverlappedObject *self)
  1347. {
  1348. return PyLong_FromVoidPtr(&self->overlapped);
  1349. }
  1350. static PyObject*
  1351. Overlapped_getpending(OverlappedObject *self)
  1352. {
  1353. return PyBool_FromLong(!HasOverlappedIoCompleted(&self->overlapped) &&
  1354. self->type != TYPE_NOT_STARTED);
  1355. }
  1356. static int
  1357. Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
  1358. {
  1359. switch (self->type) {
  1360. case TYPE_READ:
  1361. case TYPE_ACCEPT:
  1362. Py_VISIT(self->allocated_buffer);
  1363. break;
  1364. case TYPE_WRITE:
  1365. case TYPE_WRITE_TO:
  1366. case TYPE_READINTO:
  1367. if (self->user_buffer.obj) {
  1368. Py_VISIT(&self->user_buffer.obj);
  1369. }
  1370. break;
  1371. case TYPE_READ_FROM:
  1372. Py_VISIT(self->read_from.result);
  1373. Py_VISIT(self->read_from.allocated_buffer);
  1374. break;
  1375. case TYPE_READ_FROM_INTO:
  1376. Py_VISIT(self->read_from_into.result);
  1377. if (self->read_from_into.user_buffer.obj) {
  1378. Py_VISIT(&self->read_from_into.user_buffer.obj);
  1379. }
  1380. break;
  1381. }
  1382. return 0;
  1383. }
  1384. // UDP functions
  1385. /*
  1386. * Note: WSAConnect does not support Overlapped I/O so this function should
  1387. * _only_ be used for connectionless sockets (UDP).
  1388. */
  1389. /*[clinic input]
  1390. _overlapped.WSAConnect
  1391. client_handle as ConnectSocket: HANDLE
  1392. address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
  1393. /
  1394. Bind a remote address to a connectionless (UDP) socket.
  1395. [clinic start generated code]*/
  1396. static PyObject *
  1397. _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket,
  1398. PyObject *AddressObj)
  1399. /*[clinic end generated code: output=ea0b4391e94dad63 input=7cf65313d49c015a]*/
  1400. {
  1401. char AddressBuf[sizeof(struct sockaddr_in6)];
  1402. SOCKADDR *Address = (SOCKADDR*)AddressBuf;
  1403. int Length;
  1404. int err;
  1405. Length = sizeof(AddressBuf);
  1406. Length = parse_address(AddressObj, Address, Length);
  1407. if (Length < 0) {
  1408. return NULL;
  1409. }
  1410. Py_BEGIN_ALLOW_THREADS
  1411. // WSAConnect does not support overlapped I/O so this call will
  1412. // successfully complete immediately.
  1413. err = WSAConnect((SOCKET)ConnectSocket, Address, Length,
  1414. NULL, NULL, NULL, NULL);
  1415. Py_END_ALLOW_THREADS
  1416. if (err == 0) {
  1417. Py_RETURN_NONE;
  1418. }
  1419. else {
  1420. return SetFromWindowsErr(WSAGetLastError());
  1421. }
  1422. }
  1423. /*[clinic input]
  1424. _overlapped.Overlapped.WSASendTo
  1425. handle: HANDLE
  1426. buf as bufobj: Py_buffer
  1427. flags: DWORD
  1428. address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type')
  1429. /
  1430. Start overlapped sendto over a connectionless (UDP) socket.
  1431. [clinic start generated code]*/
  1432. static PyObject *
  1433. _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
  1434. Py_buffer *bufobj, DWORD flags,
  1435. PyObject *AddressObj)
  1436. /*[clinic end generated code: output=3cdedc4cfaeb70cd input=31f44cd4ab92fc33]*/
  1437. {
  1438. char AddressBuf[sizeof(struct sockaddr_in6)];
  1439. SOCKADDR *Address = (SOCKADDR*)AddressBuf;
  1440. int AddressLength;
  1441. DWORD written;
  1442. WSABUF wsabuf;
  1443. int ret;
  1444. DWORD err;
  1445. // Parse the "to" address
  1446. AddressLength = sizeof(AddressBuf);
  1447. AddressLength = parse_address(AddressObj, Address, AddressLength);
  1448. if (AddressLength < 0) {
  1449. return NULL;
  1450. }
  1451. if (self->type != TYPE_NONE) {
  1452. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1453. return NULL;
  1454. }
  1455. #if SIZEOF_SIZE_T > SIZEOF_LONG
  1456. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  1457. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1458. return NULL;
  1459. }
  1460. #endif
  1461. steal_buffer(&self->user_buffer, bufobj);
  1462. self->type = TYPE_WRITE_TO;
  1463. self->handle = handle;
  1464. wsabuf.len = (DWORD)self->user_buffer.len;
  1465. wsabuf.buf = self->user_buffer.buf;
  1466. Py_BEGIN_ALLOW_THREADS
  1467. ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags,
  1468. Address, AddressLength, &self->overlapped, NULL);
  1469. Py_END_ALLOW_THREADS
  1470. self->error = err = (ret == SOCKET_ERROR ? WSAGetLastError() :
  1471. ERROR_SUCCESS);
  1472. switch(err) {
  1473. case ERROR_SUCCESS:
  1474. case ERROR_IO_PENDING:
  1475. Py_RETURN_NONE;
  1476. default:
  1477. self->type = TYPE_NOT_STARTED;
  1478. return SetFromWindowsErr(err);
  1479. }
  1480. }
  1481. PyDoc_STRVAR(
  1482. Overlapped_WSARecvFrom_doc,
  1483. "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n"
  1484. "Start overlapped receive");
  1485. /*[clinic input]
  1486. _overlapped.Overlapped.WSARecvFrom
  1487. handle: HANDLE
  1488. size: DWORD
  1489. flags: DWORD = 0
  1490. /
  1491. Start overlapped receive.
  1492. [clinic start generated code]*/
  1493. static PyObject *
  1494. _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self,
  1495. HANDLE handle, DWORD size,
  1496. DWORD flags)
  1497. /*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/
  1498. {
  1499. PyObject *buf;
  1500. DWORD nread;
  1501. WSABUF wsabuf;
  1502. int ret;
  1503. DWORD err;
  1504. if (self->type != TYPE_NONE) {
  1505. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1506. return NULL;
  1507. }
  1508. #if SIZEOF_SIZE_T <= SIZEOF_LONG
  1509. size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX);
  1510. #endif
  1511. buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1));
  1512. if (buf == NULL) {
  1513. return NULL;
  1514. }
  1515. wsabuf.buf = PyBytes_AS_STRING(buf);
  1516. wsabuf.len = size;
  1517. self->type = TYPE_READ_FROM;
  1518. self->handle = handle;
  1519. self->read_from.allocated_buffer = buf;
  1520. memset(&self->read_from.address, 0, sizeof(self->read_from.address));
  1521. self->read_from.address_length = sizeof(self->read_from.address);
  1522. Py_BEGIN_ALLOW_THREADS
  1523. ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
  1524. (SOCKADDR*)&self->read_from.address,
  1525. &self->read_from.address_length,
  1526. &self->overlapped, NULL);
  1527. Py_END_ALLOW_THREADS
  1528. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  1529. switch (err) {
  1530. case ERROR_BROKEN_PIPE:
  1531. mark_as_completed(&self->overlapped);
  1532. return SetFromWindowsErr(err);
  1533. case ERROR_SUCCESS:
  1534. case ERROR_MORE_DATA:
  1535. case ERROR_IO_PENDING:
  1536. Py_RETURN_NONE;
  1537. default:
  1538. self->type = TYPE_NOT_STARTED;
  1539. return SetFromWindowsErr(err);
  1540. }
  1541. }
  1542. /*[clinic input]
  1543. _overlapped.Overlapped.WSARecvFromInto
  1544. handle: HANDLE
  1545. buf as bufobj: Py_buffer
  1546. size: DWORD
  1547. flags: DWORD = 0
  1548. /
  1549. Start overlapped receive.
  1550. [clinic start generated code]*/
  1551. static PyObject *
  1552. _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self,
  1553. HANDLE handle, Py_buffer *bufobj,
  1554. DWORD size, DWORD flags)
  1555. /*[clinic end generated code: output=30c7ea171a691757 input=4be4b08d03531e76]*/
  1556. {
  1557. DWORD nread;
  1558. WSABUF wsabuf;
  1559. int ret;
  1560. DWORD err;
  1561. if (self->type != TYPE_NONE) {
  1562. PyErr_SetString(PyExc_ValueError, "operation already attempted");
  1563. return NULL;
  1564. }
  1565. #if SIZEOF_SIZE_T > SIZEOF_LONG
  1566. if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
  1567. PyErr_SetString(PyExc_ValueError, "buffer too large");
  1568. return NULL;
  1569. }
  1570. #endif
  1571. wsabuf.buf = bufobj->buf;
  1572. wsabuf.len = size;
  1573. self->type = TYPE_READ_FROM_INTO;
  1574. self->handle = handle;
  1575. steal_buffer(&self->read_from_into.user_buffer, bufobj);
  1576. memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address));
  1577. self->read_from_into.address_length = sizeof(self->read_from_into.address);
  1578. Py_BEGIN_ALLOW_THREADS
  1579. ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags,
  1580. (SOCKADDR*)&self->read_from_into.address,
  1581. &self->read_from_into.address_length,
  1582. &self->overlapped, NULL);
  1583. Py_END_ALLOW_THREADS
  1584. self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS);
  1585. switch (err) {
  1586. case ERROR_BROKEN_PIPE:
  1587. mark_as_completed(&self->overlapped);
  1588. return SetFromWindowsErr(err);
  1589. case ERROR_SUCCESS:
  1590. case ERROR_MORE_DATA:
  1591. case ERROR_IO_PENDING:
  1592. Py_RETURN_NONE;
  1593. default:
  1594. self->type = TYPE_NOT_STARTED;
  1595. return SetFromWindowsErr(err);
  1596. }
  1597. }
  1598. #include "clinic/overlapped.c.h"
  1599. static PyMethodDef Overlapped_methods[] = {
  1600. _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF
  1601. _OVERLAPPED_OVERLAPPED_CANCEL_METHODDEF
  1602. _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF
  1603. _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF
  1604. _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF
  1605. _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF
  1606. _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
  1607. _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF
  1608. _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF
  1609. _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF
  1610. _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF
  1611. _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF
  1612. _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF
  1613. _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF
  1614. _OVERLAPPED_OVERLAPPED_CONNECTNAMEDPIPE_METHODDEF
  1615. _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF
  1616. _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF
  1617. {NULL}
  1618. };
  1619. static PyMemberDef Overlapped_members[] = {
  1620. {"error", T_ULONG,
  1621. offsetof(OverlappedObject, error),
  1622. READONLY, "Error from last operation"},
  1623. {"event", T_HANDLE,
  1624. offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
  1625. READONLY, "Overlapped event handle"},
  1626. {NULL}
  1627. };
  1628. static PyGetSetDef Overlapped_getsets[] = {
  1629. {"address", (getter)Overlapped_getaddress, NULL,
  1630. "Address of overlapped structure"},
  1631. {"pending", (getter)Overlapped_getpending, NULL,
  1632. "Whether the operation is pending"},
  1633. {NULL},
  1634. };
  1635. static PyType_Slot overlapped_type_slots[] = {
  1636. {Py_tp_dealloc, Overlapped_dealloc},
  1637. {Py_tp_doc, (char *)_overlapped_Overlapped__doc__},
  1638. {Py_tp_traverse, Overlapped_traverse},
  1639. {Py_tp_methods, Overlapped_methods},
  1640. {Py_tp_members, Overlapped_members},
  1641. {Py_tp_getset, Overlapped_getsets},
  1642. {Py_tp_new, _overlapped_Overlapped},
  1643. {0,0}
  1644. };
  1645. static PyType_Spec overlapped_type_spec = {
  1646. .name = "_overlapped.Overlapped",
  1647. .basicsize = sizeof(OverlappedObject),
  1648. .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
  1649. .slots = overlapped_type_slots
  1650. };
  1651. static PyMethodDef overlapped_functions[] = {
  1652. _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF
  1653. _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF
  1654. _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF
  1655. _OVERLAPPED_FORMATMESSAGE_METHODDEF
  1656. _OVERLAPPED_BINDLOCAL_METHODDEF
  1657. _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF
  1658. _OVERLAPPED_UNREGISTERWAIT_METHODDEF
  1659. _OVERLAPPED_UNREGISTERWAITEX_METHODDEF
  1660. _OVERLAPPED_CREATEEVENT_METHODDEF
  1661. _OVERLAPPED_SETEVENT_METHODDEF
  1662. _OVERLAPPED_RESETEVENT_METHODDEF
  1663. _OVERLAPPED_OVERLAPPED_CONNECTPIPE_METHODDEF
  1664. _OVERLAPPED_WSACONNECT_METHODDEF
  1665. {NULL}
  1666. };
  1667. #define WINAPI_CONSTANT(fmt, con) \
  1668. do { \
  1669. PyObject *value = Py_BuildValue(fmt, con); \
  1670. if (value == NULL) { \
  1671. return -1; \
  1672. } \
  1673. if (PyModule_AddObject(module, #con, value) < 0 ) { \
  1674. Py_DECREF(value); \
  1675. return -1; \
  1676. } \
  1677. } while (0)
  1678. static int
  1679. overlapped_exec(PyObject *module)
  1680. {
  1681. /* Ensure WSAStartup() called before initializing function pointers */
  1682. PyObject *socket_module = PyImport_ImportModule("_socket");
  1683. if (!socket_module) {
  1684. return -1;
  1685. }
  1686. Py_DECREF(socket_module);
  1687. if (initialize_function_pointers() < 0) {
  1688. return -1;
  1689. }
  1690. PyTypeObject *overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(
  1691. module, &overlapped_type_spec, NULL);
  1692. if (overlapped_type == NULL) {
  1693. return -1;
  1694. }
  1695. int rc = PyModule_AddType(module, overlapped_type);
  1696. Py_DECREF(overlapped_type);
  1697. if (rc < 0) {
  1698. return -1;
  1699. }
  1700. WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
  1701. WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
  1702. WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED);
  1703. WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
  1704. WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
  1705. WINAPI_CONSTANT(F_DWORD, INFINITE);
  1706. WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE);
  1707. WINAPI_CONSTANT(F_HANDLE, NULL);
  1708. WINAPI_CONSTANT(F_DWORD, SO_UPDATE_ACCEPT_CONTEXT);
  1709. WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT);
  1710. WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET);
  1711. return 0;
  1712. }
  1713. static PyModuleDef_Slot overlapped_slots[] = {
  1714. {Py_mod_exec, overlapped_exec},
  1715. {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
  1716. {0, NULL}
  1717. };
  1718. static struct PyModuleDef overlapped_module = {
  1719. .m_base = PyModuleDef_HEAD_INIT,
  1720. .m_name = "_overlapped",
  1721. .m_methods = overlapped_functions,
  1722. .m_slots = overlapped_slots,
  1723. };
  1724. PyMODINIT_FUNC
  1725. PyInit__overlapped(void)
  1726. {
  1727. return PyModuleDef_Init(&overlapped_module);
  1728. }