blob: 1317fc9a172c0d8bf7a838fee0615cf4488ffbe8 [file] [log] [blame]
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001/*
2 * Support routines from the Windows API
3 *
4 * This module was originally created by merging PC/_subprocess.c with
5 * Modules/_multiprocessing/win32_functions.c.
6 *
7 * Copyright (c) 2004 by Fredrik Lundh <fredrik@pythonware.com>
8 * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com
9 * Copyright (c) 2004 by Peter Astrand <astrand@lysator.liu.se>
10 *
11 * By obtaining, using, and/or copying this software and/or its
12 * associated documentation, you agree that you have read, understood,
13 * and will comply with the following terms and conditions:
14 *
15 * Permission to use, copy, modify, and distribute this software and
16 * its associated documentation for any purpose and without fee is
17 * hereby granted, provided that the above copyright notice appears in
18 * all copies, and that both that copyright notice and this permission
19 * notice appear in supporting documentation, and that the name of the
20 * authors not be used in advertising or publicity pertaining to
21 * distribution of the software without specific, written prior
22 * permission.
23 *
24 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
25 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
26 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
27 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
28 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
29 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
30 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 *
32 */
33
34/* Licensed to PSF under a Contributor Agreement. */
35/* See http://www.python.org/2.4/license for licensing details. */
36
37#include "Python.h"
38#include "structmember.h"
39
40#define WINDOWS_LEAN_AND_MEAN
41#include "windows.h"
42#include <crtdbg.h>
Tim Golden0321cf22014-05-05 19:46:17 +010043#include "winreparse.h"
Antoine Pitrou23bba4c2012-04-18 20:51:15 +020044
45#if defined(MS_WIN32) && !defined(MS_WIN64)
46#define HANDLE_TO_PYNUM(handle) \
47 PyLong_FromUnsignedLong((unsigned long) handle)
48#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLong(obj))
49#define F_POINTER "k"
50#define T_POINTER T_ULONG
51#else
52#define HANDLE_TO_PYNUM(handle) \
53 PyLong_FromUnsignedLongLong((unsigned long long) handle)
54#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLongLong(obj))
55#define F_POINTER "K"
56#define T_POINTER T_ULONGLONG
57#endif
58
59#define F_HANDLE F_POINTER
60#define F_DWORD "k"
Antoine Pitrou23bba4c2012-04-18 20:51:15 +020061
62#define T_HANDLE T_POINTER
63
64/* Grab CancelIoEx dynamically from kernel32 */
65static int has_CancelIoEx = -1;
66static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED);
67
68static int
69check_CancelIoEx()
70{
71 if (has_CancelIoEx == -1)
72 {
73 HINSTANCE hKernel32 = GetModuleHandle("KERNEL32");
74 * (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32,
75 "CancelIoEx");
76 has_CancelIoEx = (Py_CancelIoEx != NULL);
77 }
78 return has_CancelIoEx;
79}
80
81
82/*
83 * A Python object wrapping an OVERLAPPED structure and other useful data
84 * for overlapped I/O
85 */
86
87typedef struct {
88 PyObject_HEAD
89 OVERLAPPED overlapped;
90 /* For convenience, we store the file handle too */
91 HANDLE handle;
92 /* Whether there's I/O in flight */
93 int pending;
94 /* Whether I/O completed successfully */
95 int completed;
96 /* Buffer used for reading (optional) */
97 PyObject *read_buffer;
98 /* Buffer used for writing (optional) */
99 Py_buffer write_buffer;
100} OverlappedObject;
101
102static void
103overlapped_dealloc(OverlappedObject *self)
104{
105 DWORD bytes;
106 int err = GetLastError();
Richard Oudkerk633db6f2013-11-17 13:15:51 +0000107
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200108 if (self->pending) {
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200109 if (check_CancelIoEx() &&
Richard Oudkerk633db6f2013-11-17 13:15:51 +0000110 Py_CancelIoEx(self->handle, &self->overlapped) &&
111 GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE))
112 {
113 /* The operation is no longer pending -- nothing to do. */
114 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600115 else if (_Py_IsFinalizing())
Richard Oudkerk633db6f2013-11-17 13:15:51 +0000116 {
117 /* The operation is still pending -- give a warning. This
118 will probably only happen on Windows XP. */
119 PyErr_SetString(PyExc_RuntimeError,
120 "I/O operations still in flight while destroying "
121 "Overlapped object, the process may crash");
122 PyErr_WriteUnraisable(NULL);
123 }
124 else
125 {
126 /* The operation is still pending, but the process is
127 probably about to exit, so we need not worry too much
128 about memory leaks. Leaking self prevents a potential
129 crash. This can happen when a daemon thread is cleaned
130 up at exit -- see #19565. We only expect to get here
131 on Windows XP. */
132 CloseHandle(self->overlapped.hEvent);
133 SetLastError(err);
134 return;
135 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200136 }
Richard Oudkerk633db6f2013-11-17 13:15:51 +0000137
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200138 CloseHandle(self->overlapped.hEvent);
139 SetLastError(err);
140 if (self->write_buffer.obj)
141 PyBuffer_Release(&self->write_buffer);
142 Py_CLEAR(self->read_buffer);
143 PyObject_Del(self);
144}
145
Zachary Waref2244ea2015-05-13 01:22:54 -0500146/*[clinic input]
147module _winapi
148class _winapi.Overlapped "OverlappedObject *" "&OverlappedType"
149[clinic start generated code]*/
150/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c13d3f5fd1dabb84]*/
151
152/*[python input]
153def create_converter(type_, format_unit):
154 name = type_ + '_converter'
155 # registered upon creation by CConverter's metaclass
156 type(name, (CConverter,), {'type': type_, 'format_unit': format_unit})
157
158# format unit differs between platforms for these
159create_converter('HANDLE', '" F_HANDLE "')
160create_converter('HMODULE', '" F_HANDLE "')
161create_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "')
Davin Pottse895de32019-02-23 22:08:16 -0600162create_converter('LPCVOID', '" F_POINTER "')
Zachary Waref2244ea2015-05-13 01:22:54 -0500163
164create_converter('BOOL', 'i') # F_BOOL used previously (always 'i')
165create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter)
166create_converter('LPCTSTR', 's')
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200167create_converter('LPCWSTR', 'u')
Zachary Waref2244ea2015-05-13 01:22:54 -0500168create_converter('LPWSTR', 'u')
169create_converter('UINT', 'I') # F_UINT used previously (always 'I')
170
171class HANDLE_return_converter(CReturnConverter):
172 type = 'HANDLE'
173
174 def render(self, function, data):
175 self.declare(data)
176 self.err_occurred_if("_return_value == INVALID_HANDLE_VALUE", data)
177 data.return_conversion.append(
Serhiy Storchaka5dee6552016-06-09 16:16:06 +0300178 'if (_return_value == NULL) {\n Py_RETURN_NONE;\n}\n')
Zachary Waref2244ea2015-05-13 01:22:54 -0500179 data.return_conversion.append(
180 'return_value = HANDLE_TO_PYNUM(_return_value);\n')
181
182class DWORD_return_converter(CReturnConverter):
183 type = 'DWORD'
184
185 def render(self, function, data):
186 self.declare(data)
Victor Stinner850a18e2017-10-24 16:53:32 -0700187 self.err_occurred_if("_return_value == PY_DWORD_MAX", data)
Zachary Waref2244ea2015-05-13 01:22:54 -0500188 data.return_conversion.append(
189 'return_value = Py_BuildValue("k", _return_value);\n')
Davin Pottse895de32019-02-23 22:08:16 -0600190
191class LPVOID_return_converter(CReturnConverter):
192 type = 'LPVOID'
193
194 def render(self, function, data):
195 self.declare(data)
196 self.err_occurred_if("_return_value == NULL", data)
197 data.return_conversion.append(
198 'return_value = HANDLE_TO_PYNUM(_return_value);\n')
Zachary Waref2244ea2015-05-13 01:22:54 -0500199[python start generated code]*/
Davin Pottse895de32019-02-23 22:08:16 -0600200/*[python end generated code: output=da39a3ee5e6b4b0d input=79464c61a31ae932]*/
Zachary Waref2244ea2015-05-13 01:22:54 -0500201
202#include "clinic/_winapi.c.h"
203
204/*[clinic input]
205_winapi.Overlapped.GetOverlappedResult
206
207 wait: bool
208 /
209[clinic start generated code]*/
210
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200211static PyObject *
Zachary Waref2244ea2015-05-13 01:22:54 -0500212_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait)
213/*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200214{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200215 BOOL res;
216 DWORD transferred = 0;
217 DWORD err;
218
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200219 Py_BEGIN_ALLOW_THREADS
220 res = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
221 wait != 0);
222 Py_END_ALLOW_THREADS
223
224 err = res ? ERROR_SUCCESS : GetLastError();
225 switch (err) {
226 case ERROR_SUCCESS:
227 case ERROR_MORE_DATA:
228 case ERROR_OPERATION_ABORTED:
229 self->completed = 1;
230 self->pending = 0;
231 break;
232 case ERROR_IO_INCOMPLETE:
233 break;
234 default:
235 self->pending = 0;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300236 return PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200237 }
238 if (self->completed && self->read_buffer != NULL) {
239 assert(PyBytes_CheckExact(self->read_buffer));
240 if (transferred != PyBytes_GET_SIZE(self->read_buffer) &&
241 _PyBytes_Resize(&self->read_buffer, transferred))
242 return NULL;
243 }
244 return Py_BuildValue("II", (unsigned) transferred, (unsigned) err);
245}
246
Zachary Waref2244ea2015-05-13 01:22:54 -0500247/*[clinic input]
248_winapi.Overlapped.getbuffer
249[clinic start generated code]*/
250
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200251static PyObject *
Zachary Waref2244ea2015-05-13 01:22:54 -0500252_winapi_Overlapped_getbuffer_impl(OverlappedObject *self)
253/*[clinic end generated code: output=95a3eceefae0f748 input=347fcfd56b4ceabd]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200254{
255 PyObject *res;
256 if (!self->completed) {
257 PyErr_SetString(PyExc_ValueError,
258 "can't get read buffer before GetOverlappedResult() "
259 "signals the operation completed");
260 return NULL;
261 }
262 res = self->read_buffer ? self->read_buffer : Py_None;
263 Py_INCREF(res);
264 return res;
265}
266
Zachary Waref2244ea2015-05-13 01:22:54 -0500267/*[clinic input]
268_winapi.Overlapped.cancel
269[clinic start generated code]*/
270
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200271static PyObject *
Zachary Waref2244ea2015-05-13 01:22:54 -0500272_winapi_Overlapped_cancel_impl(OverlappedObject *self)
273/*[clinic end generated code: output=fcb9ab5df4ebdae5 input=cbf3da142290039f]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200274{
275 BOOL res = TRUE;
276
277 if (self->pending) {
278 Py_BEGIN_ALLOW_THREADS
279 if (check_CancelIoEx())
280 res = Py_CancelIoEx(self->handle, &self->overlapped);
281 else
282 res = CancelIo(self->handle);
283 Py_END_ALLOW_THREADS
284 }
285
286 /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */
287 if (!res && GetLastError() != ERROR_NOT_FOUND)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300288 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200289 self->pending = 0;
290 Py_RETURN_NONE;
291}
292
293static PyMethodDef overlapped_methods[] = {
Zachary Waref2244ea2015-05-13 01:22:54 -0500294 _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF
295 _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF
296 _WINAPI_OVERLAPPED_CANCEL_METHODDEF
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200297 {NULL}
298};
299
300static PyMemberDef overlapped_members[] = {
301 {"event", T_HANDLE,
302 offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
303 READONLY, "overlapped event handle"},
304 {NULL}
305};
306
307PyTypeObject OverlappedType = {
308 PyVarObject_HEAD_INIT(NULL, 0)
309 /* tp_name */ "_winapi.Overlapped",
310 /* tp_basicsize */ sizeof(OverlappedObject),
311 /* tp_itemsize */ 0,
312 /* tp_dealloc */ (destructor) overlapped_dealloc,
313 /* tp_print */ 0,
314 /* tp_getattr */ 0,
315 /* tp_setattr */ 0,
316 /* tp_reserved */ 0,
317 /* tp_repr */ 0,
318 /* tp_as_number */ 0,
319 /* tp_as_sequence */ 0,
320 /* tp_as_mapping */ 0,
321 /* tp_hash */ 0,
322 /* tp_call */ 0,
323 /* tp_str */ 0,
324 /* tp_getattro */ 0,
325 /* tp_setattro */ 0,
326 /* tp_as_buffer */ 0,
327 /* tp_flags */ Py_TPFLAGS_DEFAULT,
328 /* tp_doc */ "OVERLAPPED structure wrapper",
329 /* tp_traverse */ 0,
330 /* tp_clear */ 0,
331 /* tp_richcompare */ 0,
332 /* tp_weaklistoffset */ 0,
333 /* tp_iter */ 0,
334 /* tp_iternext */ 0,
335 /* tp_methods */ overlapped_methods,
336 /* tp_members */ overlapped_members,
337 /* tp_getset */ 0,
338 /* tp_base */ 0,
339 /* tp_dict */ 0,
340 /* tp_descr_get */ 0,
341 /* tp_descr_set */ 0,
342 /* tp_dictoffset */ 0,
343 /* tp_init */ 0,
344 /* tp_alloc */ 0,
345 /* tp_new */ 0,
346};
347
348static OverlappedObject *
349new_overlapped(HANDLE handle)
350{
351 OverlappedObject *self;
352
353 self = PyObject_New(OverlappedObject, &OverlappedType);
354 if (!self)
355 return NULL;
356 self->handle = handle;
357 self->read_buffer = NULL;
358 self->pending = 0;
359 self->completed = 0;
360 memset(&self->overlapped, 0, sizeof(OVERLAPPED));
361 memset(&self->write_buffer, 0, sizeof(Py_buffer));
362 /* Manual reset, initially non-signalled */
363 self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
364 return self;
365}
366
367/* -------------------------------------------------------------------- */
368/* windows API functions */
369
Zachary Waref2244ea2015-05-13 01:22:54 -0500370/*[clinic input]
371_winapi.CloseHandle
372
373 handle: HANDLE
374 /
375
376Close handle.
377[clinic start generated code]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200378
379static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300380_winapi_CloseHandle_impl(PyObject *module, HANDLE handle)
381/*[clinic end generated code: output=7ad37345f07bd782 input=7f0e4ac36e0352b8]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200382{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200383 BOOL success;
384
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200385 Py_BEGIN_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -0500386 success = CloseHandle(handle);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200387 Py_END_ALLOW_THREADS
388
389 if (!success)
390 return PyErr_SetFromWindowsErr(0);
391
392 Py_RETURN_NONE;
393}
394
Zachary Waref2244ea2015-05-13 01:22:54 -0500395/*[clinic input]
396_winapi.ConnectNamedPipe
397
398 handle: HANDLE
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200399 overlapped as use_overlapped: bool(accept={int}) = False
Zachary Waref2244ea2015-05-13 01:22:54 -0500400[clinic start generated code]*/
401
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300403_winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
Zachary Ware77772c02015-05-13 10:58:35 -0500404 int use_overlapped)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200405/*[clinic end generated code: output=335a0e7086800671 input=34f937c1c86e5e68]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200406{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200407 BOOL success;
408 OverlappedObject *overlapped = NULL;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200409
410 if (use_overlapped) {
Zachary Waref2244ea2015-05-13 01:22:54 -0500411 overlapped = new_overlapped(handle);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200412 if (!overlapped)
413 return NULL;
414 }
415
416 Py_BEGIN_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -0500417 success = ConnectNamedPipe(handle,
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200418 overlapped ? &overlapped->overlapped : NULL);
419 Py_END_ALLOW_THREADS
420
421 if (overlapped) {
422 int err = GetLastError();
423 /* Overlapped ConnectNamedPipe never returns a success code */
424 assert(success == 0);
425 if (err == ERROR_IO_PENDING)
426 overlapped->pending = 1;
427 else if (err == ERROR_PIPE_CONNECTED)
428 SetEvent(overlapped->overlapped.hEvent);
429 else {
430 Py_DECREF(overlapped);
431 return PyErr_SetFromWindowsErr(err);
432 }
433 return (PyObject *) overlapped;
434 }
435 if (!success)
436 return PyErr_SetFromWindowsErr(0);
437
438 Py_RETURN_NONE;
439}
440
Zachary Waref2244ea2015-05-13 01:22:54 -0500441/*[clinic input]
442_winapi.CreateFile -> HANDLE
443
444 file_name: LPCTSTR
445 desired_access: DWORD
446 share_mode: DWORD
447 security_attributes: LPSECURITY_ATTRIBUTES
448 creation_disposition: DWORD
449 flags_and_attributes: DWORD
450 template_file: HANDLE
451 /
452[clinic start generated code]*/
453
454static HANDLE
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300455_winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name,
Zachary Ware77772c02015-05-13 10:58:35 -0500456 DWORD desired_access, DWORD share_mode,
457 LPSECURITY_ATTRIBUTES security_attributes,
458 DWORD creation_disposition,
459 DWORD flags_and_attributes, HANDLE template_file)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300460/*[clinic end generated code: output=417ddcebfc5a3d53 input=6423c3e40372dbd5]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200461{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200462 HANDLE handle;
463
Steve Dowerb82e17e2019-05-23 08:45:22 -0700464 if (PySys_Audit("_winapi.CreateFile", "uIIII",
465 file_name, desired_access, share_mode,
466 creation_disposition, flags_and_attributes) < 0) {
467 return INVALID_HANDLE_VALUE;
468 }
469
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200470 Py_BEGIN_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -0500471 handle = CreateFile(file_name, desired_access,
472 share_mode, security_attributes,
473 creation_disposition,
474 flags_and_attributes, template_file);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200475 Py_END_ALLOW_THREADS
476
477 if (handle == INVALID_HANDLE_VALUE)
Zachary Waref2244ea2015-05-13 01:22:54 -0500478 PyErr_SetFromWindowsErr(0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200479
Zachary Waref2244ea2015-05-13 01:22:54 -0500480 return handle;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200481}
482
Zachary Waref2244ea2015-05-13 01:22:54 -0500483/*[clinic input]
Davin Pottse895de32019-02-23 22:08:16 -0600484_winapi.CreateFileMapping -> HANDLE
485
486 file_handle: HANDLE
487 security_attributes: LPSECURITY_ATTRIBUTES
488 protect: DWORD
489 max_size_high: DWORD
490 max_size_low: DWORD
491 name: LPCWSTR
492 /
493[clinic start generated code]*/
494
495static HANDLE
496_winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle,
497 LPSECURITY_ATTRIBUTES security_attributes,
498 DWORD protect, DWORD max_size_high,
499 DWORD max_size_low, LPCWSTR name)
500/*[clinic end generated code: output=6c0a4d5cf7f6fcc6 input=3dc5cf762a74dee8]*/
501{
502 HANDLE handle;
503
504 Py_BEGIN_ALLOW_THREADS
505 handle = CreateFileMappingW(file_handle, security_attributes,
506 protect, max_size_high, max_size_low,
507 name);
508 Py_END_ALLOW_THREADS
509
510 if (handle == NULL) {
511 PyErr_SetFromWindowsErrWithUnicodeFilename(0, name);
512 handle = INVALID_HANDLE_VALUE;
513 }
514
515 return handle;
516}
517
518/*[clinic input]
Zachary Waref2244ea2015-05-13 01:22:54 -0500519_winapi.CreateJunction
Tim Golden0321cf22014-05-05 19:46:17 +0100520
Zachary Waref2244ea2015-05-13 01:22:54 -0500521 src_path: LPWSTR
522 dst_path: LPWSTR
523 /
524[clinic start generated code]*/
525
526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300527_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path,
Zachary Ware77772c02015-05-13 10:58:35 -0500528 LPWSTR dst_path)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300529/*[clinic end generated code: output=66b7eb746e1dfa25 input=8cd1f9964b6e3d36]*/
Zachary Waref2244ea2015-05-13 01:22:54 -0500530{
Tim Golden0321cf22014-05-05 19:46:17 +0100531 /* Privilege adjustment */
532 HANDLE token = NULL;
533 TOKEN_PRIVILEGES tp;
534
535 /* Reparse data buffer */
536 const USHORT prefix_len = 4;
537 USHORT print_len = 0;
538 USHORT rdb_size = 0;
Martin Panter70214ad2016-08-04 02:38:59 +0000539 _Py_PREPARSE_DATA_BUFFER rdb = NULL;
Tim Golden0321cf22014-05-05 19:46:17 +0100540
541 /* Junction point creation */
542 HANDLE junction = NULL;
543 DWORD ret = 0;
544
Tim Golden0321cf22014-05-05 19:46:17 +0100545 if (src_path == NULL || dst_path == NULL)
546 return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);
547
548 if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0)
549 return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);
550
Steve Dowerb82e17e2019-05-23 08:45:22 -0700551 if (PySys_Audit("_winapi.CreateJunction", "uu", src_path, dst_path) < 0) {
552 return NULL;
553 }
554
Tim Golden0321cf22014-05-05 19:46:17 +0100555 /* Adjust privileges to allow rewriting directory entry as a
556 junction point. */
557 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
558 goto cleanup;
559
560 if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid))
561 goto cleanup;
562
563 tp.PrivilegeCount = 1;
564 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
565 if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
566 NULL, NULL))
567 goto cleanup;
568
569 if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES)
570 goto cleanup;
571
572 /* Store the absolute link target path length in print_len. */
573 print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL);
574 if (print_len == 0)
575 goto cleanup;
576
577 /* NUL terminator should not be part of print_len. */
578 --print_len;
579
580 /* REPARSE_DATA_BUFFER usage is heavily under-documented, especially for
581 junction points. Here's what I've learned along the way:
582 - A junction point has two components: a print name and a substitute
583 name. They both describe the link target, but the substitute name is
584 the physical target and the print name is shown in directory listings.
585 - The print name must be a native name, prefixed with "\??\".
586 - Both names are stored after each other in the same buffer (the
587 PathBuffer) and both must be NUL-terminated.
588 - There are four members defining their respective offset and length
589 inside PathBuffer: SubstituteNameOffset, SubstituteNameLength,
590 PrintNameOffset and PrintNameLength.
591 - The total size we need to allocate for the REPARSE_DATA_BUFFER, thus,
592 is the sum of:
593 - the fixed header size (REPARSE_DATA_BUFFER_HEADER_SIZE)
594 - the size of the MountPointReparseBuffer member without the PathBuffer
595 - the size of the prefix ("\??\") in bytes
596 - the size of the print name in bytes
597 - the size of the substitute name in bytes
598 - the size of two NUL terminators in bytes */
Martin Panter70214ad2016-08-04 02:38:59 +0000599 rdb_size = _Py_REPARSE_DATA_BUFFER_HEADER_SIZE +
Tim Golden0321cf22014-05-05 19:46:17 +0100600 sizeof(rdb->MountPointReparseBuffer) -
601 sizeof(rdb->MountPointReparseBuffer.PathBuffer) +
602 /* Two +1's for NUL terminators. */
603 (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR);
Martin Panter70214ad2016-08-04 02:38:59 +0000604 rdb = (_Py_PREPARSE_DATA_BUFFER)PyMem_RawMalloc(rdb_size);
Tim Golden0321cf22014-05-05 19:46:17 +0100605 if (rdb == NULL)
606 goto cleanup;
607
608 memset(rdb, 0, rdb_size);
609 rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
Martin Panter70214ad2016-08-04 02:38:59 +0000610 rdb->ReparseDataLength = rdb_size - _Py_REPARSE_DATA_BUFFER_HEADER_SIZE;
Tim Golden0321cf22014-05-05 19:46:17 +0100611 rdb->MountPointReparseBuffer.SubstituteNameOffset = 0;
612 rdb->MountPointReparseBuffer.SubstituteNameLength =
613 (prefix_len + print_len) * sizeof(WCHAR);
614 rdb->MountPointReparseBuffer.PrintNameOffset =
615 rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
616 rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR);
617
618 /* Store the full native path of link target at the substitute name
619 offset (0). */
620 wcscpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\");
621 if (GetFullPathNameW(src_path, print_len + 1,
622 rdb->MountPointReparseBuffer.PathBuffer + prefix_len,
623 NULL) == 0)
624 goto cleanup;
625
626 /* Copy everything but the native prefix to the print name offset. */
627 wcscpy(rdb->MountPointReparseBuffer.PathBuffer +
628 prefix_len + print_len + 1,
629 rdb->MountPointReparseBuffer.PathBuffer + prefix_len);
630
631 /* Create a directory for the junction point. */
632 if (!CreateDirectoryW(dst_path, NULL))
633 goto cleanup;
634
635 junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
636 OPEN_EXISTING,
637 FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
638 if (junction == INVALID_HANDLE_VALUE)
639 goto cleanup;
640
641 /* Make the directory entry a junction point. */
642 if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size,
643 NULL, 0, &ret, NULL))
644 goto cleanup;
645
646cleanup:
647 ret = GetLastError();
648
649 CloseHandle(token);
650 CloseHandle(junction);
651 PyMem_RawFree(rdb);
652
653 if (ret != 0)
654 return PyErr_SetFromWindowsErr(ret);
655
656 Py_RETURN_NONE;
657}
658
Zachary Waref2244ea2015-05-13 01:22:54 -0500659/*[clinic input]
660_winapi.CreateNamedPipe -> HANDLE
661
662 name: LPCTSTR
663 open_mode: DWORD
664 pipe_mode: DWORD
665 max_instances: DWORD
666 out_buffer_size: DWORD
667 in_buffer_size: DWORD
668 default_timeout: DWORD
669 security_attributes: LPSECURITY_ATTRIBUTES
670 /
671[clinic start generated code]*/
672
673static HANDLE
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300674_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode,
675 DWORD pipe_mode, DWORD max_instances,
676 DWORD out_buffer_size, DWORD in_buffer_size,
677 DWORD default_timeout,
Zachary Ware77772c02015-05-13 10:58:35 -0500678 LPSECURITY_ATTRIBUTES security_attributes)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300679/*[clinic end generated code: output=80f8c07346a94fbc input=5a73530b84d8bc37]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200680{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200681 HANDLE handle;
682
Steve Dowerb82e17e2019-05-23 08:45:22 -0700683 if (PySys_Audit("_winapi.CreateNamedPipe", "uII",
684 name, open_mode, pipe_mode) < 0) {
685 return INVALID_HANDLE_VALUE;
686 }
687
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200688 Py_BEGIN_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -0500689 handle = CreateNamedPipe(name, open_mode, pipe_mode,
690 max_instances, out_buffer_size,
691 in_buffer_size, default_timeout,
692 security_attributes);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200693 Py_END_ALLOW_THREADS
694
695 if (handle == INVALID_HANDLE_VALUE)
Zachary Waref2244ea2015-05-13 01:22:54 -0500696 PyErr_SetFromWindowsErr(0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200697
Zachary Waref2244ea2015-05-13 01:22:54 -0500698 return handle;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200699}
700
Zachary Waref2244ea2015-05-13 01:22:54 -0500701/*[clinic input]
702_winapi.CreatePipe
703
704 pipe_attrs: object
705 Ignored internally, can be None.
706 size: DWORD
707 /
708
709Create an anonymous pipe.
710
711Returns a 2-tuple of handles, to the read and write ends of the pipe.
712[clinic start generated code]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200713
714static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300715_winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size)
716/*[clinic end generated code: output=1c4411d8699f0925 input=c4f2cfa56ef68d90]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200717{
718 HANDLE read_pipe;
719 HANDLE write_pipe;
720 BOOL result;
721
Steve Dowerb82e17e2019-05-23 08:45:22 -0700722 if (PySys_Audit("_winapi.CreatePipe", NULL) < 0) {
723 return NULL;
724 }
725
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200726 Py_BEGIN_ALLOW_THREADS
727 result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
728 Py_END_ALLOW_THREADS
729
730 if (! result)
731 return PyErr_SetFromWindowsErr(GetLastError());
732
733 return Py_BuildValue(
734 "NN", HANDLE_TO_PYNUM(read_pipe), HANDLE_TO_PYNUM(write_pipe));
735}
736
737/* helpers for createprocess */
738
739static unsigned long
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200740getulong(PyObject* obj, const char* name)
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200741{
742 PyObject* value;
743 unsigned long ret;
744
745 value = PyObject_GetAttrString(obj, name);
746 if (! value) {
747 PyErr_Clear(); /* FIXME: propagate error? */
748 return 0;
749 }
750 ret = PyLong_AsUnsignedLong(value);
751 Py_DECREF(value);
752 return ret;
753}
754
755static HANDLE
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200756gethandle(PyObject* obj, const char* name)
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200757{
758 PyObject* value;
759 HANDLE ret;
760
761 value = PyObject_GetAttrString(obj, name);
762 if (! value) {
763 PyErr_Clear(); /* FIXME: propagate error? */
764 return NULL;
765 }
766 if (value == Py_None)
767 ret = NULL;
768 else
769 ret = PYNUM_TO_HANDLE(value);
770 Py_DECREF(value);
771 return ret;
772}
773
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200774static wchar_t *
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200775getenvironment(PyObject* environment)
776{
777 Py_ssize_t i, envsize, totalsize;
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200778 wchar_t *buffer = NULL, *p, *end;
779 PyObject *keys, *values;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200780
Ezio Melotti85a86292013-08-17 16:57:41 +0300781 /* convert environment dictionary to windows environment string */
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200782 if (! PyMapping_Check(environment)) {
783 PyErr_SetString(
784 PyExc_TypeError, "environment must be dictionary or None");
785 return NULL;
786 }
787
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200788 keys = PyMapping_Keys(environment);
Oren Milman0b3a87e2017-09-14 22:30:28 +0300789 if (!keys) {
790 return NULL;
791 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200792 values = PyMapping_Values(environment);
Oren Milman0b3a87e2017-09-14 22:30:28 +0300793 if (!values) {
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200794 goto error;
Oren Milman0b3a87e2017-09-14 22:30:28 +0300795 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200796
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200797 envsize = PyList_GET_SIZE(keys);
798 if (PyList_GET_SIZE(values) != envsize) {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +0300799 PyErr_SetString(PyExc_RuntimeError,
800 "environment changed size during iteration");
801 goto error;
802 }
803
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200804 totalsize = 1; /* trailing null character */
805 for (i = 0; i < envsize; i++) {
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200806 PyObject* key = PyList_GET_ITEM(keys, i);
807 PyObject* value = PyList_GET_ITEM(values, i);
808 Py_ssize_t size;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200809
810 if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) {
811 PyErr_SetString(PyExc_TypeError,
812 "environment can only contain strings");
813 goto error;
814 }
Serhiy Storchakad174d242017-06-23 19:39:27 +0300815 if (PyUnicode_FindChar(key, '\0', 0, PyUnicode_GET_LENGTH(key), 1) != -1 ||
816 PyUnicode_FindChar(value, '\0', 0, PyUnicode_GET_LENGTH(value), 1) != -1)
817 {
818 PyErr_SetString(PyExc_ValueError, "embedded null character");
819 goto error;
820 }
821 /* Search from index 1 because on Windows starting '=' is allowed for
822 defining hidden environment variables. */
823 if (PyUnicode_GET_LENGTH(key) == 0 ||
824 PyUnicode_FindChar(key, '=', 1, PyUnicode_GET_LENGTH(key), 1) != -1)
825 {
826 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
827 goto error;
828 }
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200829
830 size = PyUnicode_AsWideChar(key, NULL, 0);
831 assert(size > 1);
832 if (totalsize > PY_SSIZE_T_MAX - size) {
Benjamin Peterson8ce68062015-02-09 20:58:12 -0500833 PyErr_SetString(PyExc_OverflowError, "environment too long");
834 goto error;
835 }
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200836 totalsize += size; /* including '=' */
837
838 size = PyUnicode_AsWideChar(value, NULL, 0);
839 assert(size > 0);
840 if (totalsize > PY_SSIZE_T_MAX - size) {
Benjamin Peterson8ce68062015-02-09 20:58:12 -0500841 PyErr_SetString(PyExc_OverflowError, "environment too long");
842 goto error;
843 }
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200844 totalsize += size; /* including trailing '\0' */
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200845 }
846
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200847 buffer = PyMem_NEW(wchar_t, totalsize);
Benjamin Peterson8ce68062015-02-09 20:58:12 -0500848 if (! buffer) {
849 PyErr_NoMemory();
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200850 goto error;
Benjamin Peterson8ce68062015-02-09 20:58:12 -0500851 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200852 p = buffer;
853 end = buffer + totalsize;
854
855 for (i = 0; i < envsize; i++) {
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200856 PyObject* key = PyList_GET_ITEM(keys, i);
857 PyObject* value = PyList_GET_ITEM(values, i);
858 Py_ssize_t size = PyUnicode_AsWideChar(key, p, end - p);
859 assert(1 <= size && size < end - p);
860 p += size;
861 *p++ = L'=';
862 size = PyUnicode_AsWideChar(value, p, end - p);
863 assert(0 <= size && size < end - p);
864 p += size + 1;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200865 }
866
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200867 /* add trailing null character */
868 *p++ = L'\0';
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200869 assert(p == end);
870
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200871 error:
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200872 Py_XDECREF(keys);
873 Py_XDECREF(values);
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +0200874 return buffer;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +0200875}
876
Segev Finerb2a60832017-12-18 11:28:19 +0200877static LPHANDLE
878gethandlelist(PyObject *mapping, const char *name, Py_ssize_t *size)
879{
880 LPHANDLE ret = NULL;
881 PyObject *value_fast = NULL;
882 PyObject *value;
883 Py_ssize_t i;
884
885 value = PyMapping_GetItemString(mapping, name);
886 if (!value) {
887 PyErr_Clear();
888 return NULL;
889 }
890
891 if (value == Py_None) {
892 goto cleanup;
893 }
894
895 value_fast = PySequence_Fast(value, "handle_list must be a sequence or None");
896 if (value_fast == NULL)
897 goto cleanup;
898
899 *size = PySequence_Fast_GET_SIZE(value_fast) * sizeof(HANDLE);
900
901 /* Passing an empty array causes CreateProcess to fail so just don't set it */
902 if (*size == 0) {
903 goto cleanup;
904 }
905
906 ret = PyMem_Malloc(*size);
907 if (ret == NULL)
908 goto cleanup;
909
910 for (i = 0; i < PySequence_Fast_GET_SIZE(value_fast); i++) {
911 ret[i] = PYNUM_TO_HANDLE(PySequence_Fast_GET_ITEM(value_fast, i));
912 if (ret[i] == (HANDLE)-1 && PyErr_Occurred()) {
913 PyMem_Free(ret);
914 ret = NULL;
915 goto cleanup;
916 }
917 }
918
919cleanup:
920 Py_DECREF(value);
921 Py_XDECREF(value_fast);
922 return ret;
923}
924
925typedef struct {
926 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list;
927 LPHANDLE handle_list;
928} AttributeList;
929
930static void
931freeattributelist(AttributeList *attribute_list)
932{
933 if (attribute_list->attribute_list != NULL) {
934 DeleteProcThreadAttributeList(attribute_list->attribute_list);
935 PyMem_Free(attribute_list->attribute_list);
936 }
937
938 PyMem_Free(attribute_list->handle_list);
939
940 memset(attribute_list, 0, sizeof(*attribute_list));
941}
942
943static int
944getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list)
945{
946 int ret = 0;
947 DWORD err;
948 BOOL result;
949 PyObject *value;
950 Py_ssize_t handle_list_size;
951 DWORD attribute_count = 0;
952 SIZE_T attribute_list_size = 0;
953
954 value = PyObject_GetAttrString(obj, name);
955 if (!value) {
956 PyErr_Clear(); /* FIXME: propagate error? */
957 return 0;
958 }
959
960 if (value == Py_None) {
961 ret = 0;
962 goto cleanup;
963 }
964
965 if (!PyMapping_Check(value)) {
966 ret = -1;
967 PyErr_Format(PyExc_TypeError, "%s must be a mapping or None", name);
968 goto cleanup;
969 }
970
971 attribute_list->handle_list = gethandlelist(value, "handle_list", &handle_list_size);
972 if (attribute_list->handle_list == NULL && PyErr_Occurred()) {
973 ret = -1;
974 goto cleanup;
975 }
976
977 if (attribute_list->handle_list != NULL)
978 ++attribute_count;
979
980 /* Get how many bytes we need for the attribute list */
981 result = InitializeProcThreadAttributeList(NULL, attribute_count, 0, &attribute_list_size);
982 if (result || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
983 ret = -1;
984 PyErr_SetFromWindowsErr(GetLastError());
985 goto cleanup;
986 }
987
988 attribute_list->attribute_list = PyMem_Malloc(attribute_list_size);
989 if (attribute_list->attribute_list == NULL) {
990 ret = -1;
991 goto cleanup;
992 }
993
994 result = InitializeProcThreadAttributeList(
995 attribute_list->attribute_list,
996 attribute_count,
997 0,
998 &attribute_list_size);
999 if (!result) {
1000 err = GetLastError();
1001
1002 /* So that we won't call DeleteProcThreadAttributeList */
1003 PyMem_Free(attribute_list->attribute_list);
1004 attribute_list->attribute_list = NULL;
1005
1006 ret = -1;
1007 PyErr_SetFromWindowsErr(err);
1008 goto cleanup;
1009 }
1010
1011 if (attribute_list->handle_list != NULL) {
1012 result = UpdateProcThreadAttribute(
1013 attribute_list->attribute_list,
1014 0,
1015 PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
1016 attribute_list->handle_list,
1017 handle_list_size,
1018 NULL,
1019 NULL);
1020 if (!result) {
1021 ret = -1;
1022 PyErr_SetFromWindowsErr(GetLastError());
1023 goto cleanup;
1024 }
1025 }
1026
1027cleanup:
1028 Py_DECREF(value);
1029
1030 if (ret < 0)
1031 freeattributelist(attribute_list);
1032
1033 return ret;
1034}
1035
Zachary Waref2244ea2015-05-13 01:22:54 -05001036/*[clinic input]
1037_winapi.CreateProcess
1038
Zachary Ware77772c02015-05-13 10:58:35 -05001039 application_name: Py_UNICODE(accept={str, NoneType})
Vladimir Matveev7b360162018-12-14 00:30:51 -08001040 command_line: object
1041 Can be str or None
Zachary Waref2244ea2015-05-13 01:22:54 -05001042 proc_attrs: object
1043 Ignored internally, can be None.
1044 thread_attrs: object
1045 Ignored internally, can be None.
1046 inherit_handles: BOOL
1047 creation_flags: DWORD
1048 env_mapping: object
Zachary Ware77772c02015-05-13 10:58:35 -05001049 current_directory: Py_UNICODE(accept={str, NoneType})
Zachary Waref2244ea2015-05-13 01:22:54 -05001050 startup_info: object
1051 /
1052
1053Create a new process and its primary thread.
1054
1055The return value is a tuple of the process handle, thread handle,
1056process ID, and thread ID.
1057[clinic start generated code]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001058
1059static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02001060_winapi_CreateProcess_impl(PyObject *module,
1061 const Py_UNICODE *application_name,
Vladimir Matveev7b360162018-12-14 00:30:51 -08001062 PyObject *command_line, PyObject *proc_attrs,
Zachary Ware77772c02015-05-13 10:58:35 -05001063 PyObject *thread_attrs, BOOL inherit_handles,
1064 DWORD creation_flags, PyObject *env_mapping,
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02001065 const Py_UNICODE *current_directory,
Zachary Ware77772c02015-05-13 10:58:35 -05001066 PyObject *startup_info)
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02001067/*[clinic end generated code: output=9b2423a609230132 input=42ac293eaea03fc4]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001068{
Segev Finerb2a60832017-12-18 11:28:19 +02001069 PyObject *ret = NULL;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001070 BOOL result;
1071 PROCESS_INFORMATION pi;
Segev Finerb2a60832017-12-18 11:28:19 +02001072 STARTUPINFOEXW si;
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +02001073 wchar_t *wenvironment = NULL;
Vladimir Matveev7b360162018-12-14 00:30:51 -08001074 wchar_t *command_line_copy = NULL;
Segev Finerb2a60832017-12-18 11:28:19 +02001075 AttributeList attribute_list = {0};
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001076
Steve Dowerb82e17e2019-05-23 08:45:22 -07001077 if (PySys_Audit("_winapi.CreateProcess", "uuu", application_name,
1078 command_line, current_directory) < 0) {
1079 return NULL;
1080 }
1081
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001082 ZeroMemory(&si, sizeof(si));
Segev Finerb2a60832017-12-18 11:28:19 +02001083 si.StartupInfo.cb = sizeof(si);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001084
1085 /* note: we only support a small subset of all SI attributes */
Segev Finerb2a60832017-12-18 11:28:19 +02001086 si.StartupInfo.dwFlags = getulong(startup_info, "dwFlags");
1087 si.StartupInfo.wShowWindow = (WORD)getulong(startup_info, "wShowWindow");
1088 si.StartupInfo.hStdInput = gethandle(startup_info, "hStdInput");
1089 si.StartupInfo.hStdOutput = gethandle(startup_info, "hStdOutput");
1090 si.StartupInfo.hStdError = gethandle(startup_info, "hStdError");
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001091 if (PyErr_Occurred())
Segev Finerb2a60832017-12-18 11:28:19 +02001092 goto cleanup;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001093
1094 if (env_mapping != Py_None) {
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +02001095 wenvironment = getenvironment(env_mapping);
Serhiy Storchakad174d242017-06-23 19:39:27 +03001096 if (wenvironment == NULL) {
Segev Finerb2a60832017-12-18 11:28:19 +02001097 goto cleanup;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001098 }
1099 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001100
Segev Finerb2a60832017-12-18 11:28:19 +02001101 if (getattributelist(startup_info, "lpAttributeList", &attribute_list) < 0)
1102 goto cleanup;
1103
1104 si.lpAttributeList = attribute_list.attribute_list;
Vladimir Matveev7b360162018-12-14 00:30:51 -08001105 if (PyUnicode_Check(command_line)) {
1106 command_line_copy = PyUnicode_AsWideCharString(command_line, NULL);
1107 if (command_line_copy == NULL) {
1108 goto cleanup;
1109 }
1110 }
1111 else if (command_line != Py_None) {
1112 PyErr_Format(PyExc_TypeError,
1113 "CreateProcess() argument 2 must be str or None, not %s",
1114 Py_TYPE(command_line)->tp_name);
1115 goto cleanup;
1116 }
1117
Segev Finerb2a60832017-12-18 11:28:19 +02001118
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001119 Py_BEGIN_ALLOW_THREADS
1120 result = CreateProcessW(application_name,
Vladimir Matveev7b360162018-12-14 00:30:51 -08001121 command_line_copy,
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001122 NULL,
1123 NULL,
1124 inherit_handles,
Segev Finerb2a60832017-12-18 11:28:19 +02001125 creation_flags | EXTENDED_STARTUPINFO_PRESENT |
1126 CREATE_UNICODE_ENVIRONMENT,
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001127 wenvironment,
1128 current_directory,
Segev Finerb2a60832017-12-18 11:28:19 +02001129 (LPSTARTUPINFOW)&si,
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001130 &pi);
1131 Py_END_ALLOW_THREADS
1132
Segev Finerb2a60832017-12-18 11:28:19 +02001133 if (!result) {
1134 PyErr_SetFromWindowsErr(GetLastError());
1135 goto cleanup;
1136 }
1137
1138 ret = Py_BuildValue("NNkk",
1139 HANDLE_TO_PYNUM(pi.hProcess),
1140 HANDLE_TO_PYNUM(pi.hThread),
1141 pi.dwProcessId,
1142 pi.dwThreadId);
1143
1144cleanup:
Vladimir Matveev7b360162018-12-14 00:30:51 -08001145 PyMem_Free(command_line_copy);
Serhiy Storchaka8abd7c72019-03-28 16:01:34 +02001146 PyMem_Free(wenvironment);
Segev Finerb2a60832017-12-18 11:28:19 +02001147 freeattributelist(&attribute_list);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001148
Segev Finerb2a60832017-12-18 11:28:19 +02001149 return ret;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001150}
1151
Zachary Waref2244ea2015-05-13 01:22:54 -05001152/*[clinic input]
1153_winapi.DuplicateHandle -> HANDLE
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001154
Zachary Waref2244ea2015-05-13 01:22:54 -05001155 source_process_handle: HANDLE
1156 source_handle: HANDLE
1157 target_process_handle: HANDLE
1158 desired_access: DWORD
1159 inherit_handle: BOOL
1160 options: DWORD = 0
1161 /
1162
1163Return a duplicate handle object.
1164
1165The duplicate handle refers to the same object as the original
1166handle. Therefore, any changes to the object are reflected
1167through both handles.
1168[clinic start generated code]*/
1169
1170static HANDLE
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001171_winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle,
Zachary Ware77772c02015-05-13 10:58:35 -05001172 HANDLE source_handle,
1173 HANDLE target_process_handle,
1174 DWORD desired_access, BOOL inherit_handle,
1175 DWORD options)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001176/*[clinic end generated code: output=ad9711397b5dcd4e input=b933e3f2356a8c12]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001177{
1178 HANDLE target_handle;
1179 BOOL result;
1180
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001181 Py_BEGIN_ALLOW_THREADS
1182 result = DuplicateHandle(
1183 source_process_handle,
1184 source_handle,
1185 target_process_handle,
1186 &target_handle,
1187 desired_access,
1188 inherit_handle,
1189 options
1190 );
1191 Py_END_ALLOW_THREADS
1192
Zachary Waref2244ea2015-05-13 01:22:54 -05001193 if (! result) {
1194 PyErr_SetFromWindowsErr(GetLastError());
1195 return INVALID_HANDLE_VALUE;
1196 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001197
Zachary Waref2244ea2015-05-13 01:22:54 -05001198 return target_handle;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001199}
1200
Zachary Waref2244ea2015-05-13 01:22:54 -05001201/*[clinic input]
1202_winapi.ExitProcess
1203
1204 ExitCode: UINT
1205 /
1206
1207[clinic start generated code]*/
1208
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001209static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001210_winapi_ExitProcess_impl(PyObject *module, UINT ExitCode)
1211/*[clinic end generated code: output=a387deb651175301 input=4f05466a9406c558]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001212{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001213 #if defined(Py_DEBUG)
1214 SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|
1215 SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
1216 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
1217 #endif
1218
Zachary Waref2244ea2015-05-13 01:22:54 -05001219 ExitProcess(ExitCode);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001220
1221 return NULL;
1222}
1223
Zachary Waref2244ea2015-05-13 01:22:54 -05001224/*[clinic input]
1225_winapi.GetCurrentProcess -> HANDLE
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001226
Zachary Waref2244ea2015-05-13 01:22:54 -05001227Return a handle object for the current process.
1228[clinic start generated code]*/
1229
1230static HANDLE
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001231_winapi_GetCurrentProcess_impl(PyObject *module)
1232/*[clinic end generated code: output=ddeb4dd2ffadf344 input=b213403fd4b96b41]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001233{
Zachary Waref2244ea2015-05-13 01:22:54 -05001234 return GetCurrentProcess();
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001235}
1236
Zachary Waref2244ea2015-05-13 01:22:54 -05001237/*[clinic input]
1238_winapi.GetExitCodeProcess -> DWORD
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001239
Zachary Waref2244ea2015-05-13 01:22:54 -05001240 process: HANDLE
1241 /
1242
1243Return the termination status of the specified process.
1244[clinic start generated code]*/
1245
1246static DWORD
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001247_winapi_GetExitCodeProcess_impl(PyObject *module, HANDLE process)
1248/*[clinic end generated code: output=b4620bdf2bccf36b input=61b6bfc7dc2ee374]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001249{
1250 DWORD exit_code;
1251 BOOL result;
1252
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001253 result = GetExitCodeProcess(process, &exit_code);
1254
Zachary Waref2244ea2015-05-13 01:22:54 -05001255 if (! result) {
1256 PyErr_SetFromWindowsErr(GetLastError());
Victor Stinner850a18e2017-10-24 16:53:32 -07001257 exit_code = PY_DWORD_MAX;
Zachary Waref2244ea2015-05-13 01:22:54 -05001258 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001259
Zachary Waref2244ea2015-05-13 01:22:54 -05001260 return exit_code;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001261}
1262
Zachary Waref2244ea2015-05-13 01:22:54 -05001263/*[clinic input]
1264_winapi.GetLastError -> DWORD
1265[clinic start generated code]*/
1266
1267static DWORD
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001268_winapi_GetLastError_impl(PyObject *module)
1269/*[clinic end generated code: output=8585b827cb1a92c5 input=62d47fb9bce038ba]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001270{
Zachary Waref2244ea2015-05-13 01:22:54 -05001271 return GetLastError();
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001272}
1273
Zachary Waref2244ea2015-05-13 01:22:54 -05001274/*[clinic input]
1275_winapi.GetModuleFileName
1276
1277 module_handle: HMODULE
1278 /
1279
1280Return the fully-qualified path for the file that contains module.
1281
1282The module must have been loaded by the current process.
1283
1284The module parameter should be a handle to the loaded module
1285whose path is being requested. If this parameter is 0,
1286GetModuleFileName retrieves the path of the executable file
1287of the current process.
1288[clinic start generated code]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001289
1290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001291_winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle)
1292/*[clinic end generated code: output=85b4b728c5160306 input=6d66ff7deca5d11f]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001293{
1294 BOOL result;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001295 WCHAR filename[MAX_PATH];
1296
Steve Dowerb82e17e2019-05-23 08:45:22 -07001297 Py_BEGIN_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -05001298 result = GetModuleFileNameW(module_handle, filename, MAX_PATH);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001299 filename[MAX_PATH-1] = '\0';
Steve Dowerb82e17e2019-05-23 08:45:22 -07001300 Py_END_ALLOW_THREADS
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001301
1302 if (! result)
1303 return PyErr_SetFromWindowsErr(GetLastError());
1304
1305 return PyUnicode_FromWideChar(filename, wcslen(filename));
1306}
1307
Zachary Waref2244ea2015-05-13 01:22:54 -05001308/*[clinic input]
1309_winapi.GetStdHandle -> HANDLE
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001310
Zachary Waref2244ea2015-05-13 01:22:54 -05001311 std_handle: DWORD
1312 One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE.
1313 /
1314
1315Return a handle to the specified standard device.
1316
1317The integer associated with the handle object is returned.
1318[clinic start generated code]*/
1319
1320static HANDLE
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001321_winapi_GetStdHandle_impl(PyObject *module, DWORD std_handle)
1322/*[clinic end generated code: output=0e613001e73ab614 input=07016b06a2fc8826]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001323{
1324 HANDLE handle;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001325
1326 Py_BEGIN_ALLOW_THREADS
1327 handle = GetStdHandle(std_handle);
1328 Py_END_ALLOW_THREADS
1329
1330 if (handle == INVALID_HANDLE_VALUE)
Zachary Waref2244ea2015-05-13 01:22:54 -05001331 PyErr_SetFromWindowsErr(GetLastError());
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001332
Zachary Waref2244ea2015-05-13 01:22:54 -05001333 return handle;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001334}
1335
Zachary Waref2244ea2015-05-13 01:22:54 -05001336/*[clinic input]
1337_winapi.GetVersion -> long
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001338
Zachary Waref2244ea2015-05-13 01:22:54 -05001339Return the version number of the current operating system.
1340[clinic start generated code]*/
1341
1342static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001343_winapi_GetVersion_impl(PyObject *module)
1344/*[clinic end generated code: output=e41f0db5a3b82682 input=e21dff8d0baeded2]*/
Steve Dower3e96f322015-03-02 08:01:10 -08001345/* Disable deprecation warnings about GetVersionEx as the result is
1346 being passed straight through to the caller, who is responsible for
1347 using it correctly. */
1348#pragma warning(push)
1349#pragma warning(disable:4996)
1350
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001351{
Zachary Waref2244ea2015-05-13 01:22:54 -05001352 return GetVersion();
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001353}
1354
Steve Dower3e96f322015-03-02 08:01:10 -08001355#pragma warning(pop)
1356
Zachary Waref2244ea2015-05-13 01:22:54 -05001357/*[clinic input]
Davin Pottse895de32019-02-23 22:08:16 -06001358_winapi.MapViewOfFile -> LPVOID
1359
1360 file_map: HANDLE
1361 desired_access: DWORD
1362 file_offset_high: DWORD
1363 file_offset_low: DWORD
1364 number_bytes: size_t
1365 /
1366[clinic start generated code]*/
1367
1368static LPVOID
1369_winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map,
1370 DWORD desired_access, DWORD file_offset_high,
1371 DWORD file_offset_low, size_t number_bytes)
1372/*[clinic end generated code: output=f23b1ee4823663e3 input=177471073be1a103]*/
1373{
1374 LPVOID address;
1375
1376 Py_BEGIN_ALLOW_THREADS
1377 address = MapViewOfFile(file_map, desired_access, file_offset_high,
1378 file_offset_low, number_bytes);
1379 Py_END_ALLOW_THREADS
1380
1381 if (address == NULL)
1382 PyErr_SetFromWindowsErr(0);
1383
1384 return address;
1385}
1386
1387/*[clinic input]
1388_winapi.OpenFileMapping -> HANDLE
1389
1390 desired_access: DWORD
1391 inherit_handle: BOOL
1392 name: LPCWSTR
1393 /
1394[clinic start generated code]*/
1395
1396static HANDLE
1397_winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access,
1398 BOOL inherit_handle, LPCWSTR name)
1399/*[clinic end generated code: output=08cc44def1cb11f1 input=131f2a405359de7f]*/
1400{
1401 HANDLE handle;
1402
1403 Py_BEGIN_ALLOW_THREADS
1404 handle = OpenFileMappingW(desired_access, inherit_handle, name);
1405 Py_END_ALLOW_THREADS
1406
1407 if (handle == NULL) {
1408 PyErr_SetFromWindowsErrWithUnicodeFilename(0, name);
1409 handle = INVALID_HANDLE_VALUE;
1410 }
1411
1412 return handle;
1413}
1414
1415/*[clinic input]
Zachary Waref2244ea2015-05-13 01:22:54 -05001416_winapi.OpenProcess -> HANDLE
1417
1418 desired_access: DWORD
1419 inherit_handle: BOOL
1420 process_id: DWORD
1421 /
1422[clinic start generated code]*/
1423
1424static HANDLE
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001425_winapi_OpenProcess_impl(PyObject *module, DWORD desired_access,
Zachary Ware77772c02015-05-13 10:58:35 -05001426 BOOL inherit_handle, DWORD process_id)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001427/*[clinic end generated code: output=b42b6b81ea5a0fc3 input=ec98c4cf4ea2ec36]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001428{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001429 HANDLE handle;
1430
Steve Dowerb82e17e2019-05-23 08:45:22 -07001431 if (PySys_Audit("_winapi.OpenProcess", "II",
1432 process_id, desired_access) < 0) {
1433 return INVALID_HANDLE_VALUE;
1434 }
1435
1436 Py_BEGIN_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -05001437 handle = OpenProcess(desired_access, inherit_handle, process_id);
Steve Dowerb82e17e2019-05-23 08:45:22 -07001438 Py_END_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -05001439 if (handle == NULL) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07001440 PyErr_SetFromWindowsErr(GetLastError());
Zachary Waref2244ea2015-05-13 01:22:54 -05001441 handle = INVALID_HANDLE_VALUE;
1442 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001443
Zachary Waref2244ea2015-05-13 01:22:54 -05001444 return handle;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001445}
1446
Zachary Waref2244ea2015-05-13 01:22:54 -05001447/*[clinic input]
1448_winapi.PeekNamedPipe
1449
1450 handle: HANDLE
1451 size: int = 0
1452 /
1453[clinic start generated code]*/
1454
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001456_winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size)
1457/*[clinic end generated code: output=d0c3e29e49d323dd input=c7aa53bfbce69d70]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001458{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001459 PyObject *buf = NULL;
1460 DWORD nread, navail, nleft;
1461 BOOL ret;
1462
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001463 if (size < 0) {
1464 PyErr_SetString(PyExc_ValueError, "negative size");
1465 return NULL;
1466 }
1467
1468 if (size) {
1469 buf = PyBytes_FromStringAndSize(NULL, size);
1470 if (!buf)
1471 return NULL;
1472 Py_BEGIN_ALLOW_THREADS
1473 ret = PeekNamedPipe(handle, PyBytes_AS_STRING(buf), size, &nread,
1474 &navail, &nleft);
1475 Py_END_ALLOW_THREADS
1476 if (!ret) {
1477 Py_DECREF(buf);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001478 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001479 }
1480 if (_PyBytes_Resize(&buf, nread))
1481 return NULL;
Alexander Buchkovsky266f4902018-09-04 19:10:28 +03001482 return Py_BuildValue("NII", buf, navail, nleft);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001483 }
1484 else {
1485 Py_BEGIN_ALLOW_THREADS
1486 ret = PeekNamedPipe(handle, NULL, 0, NULL, &navail, &nleft);
1487 Py_END_ALLOW_THREADS
1488 if (!ret) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001489 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001490 }
Alexander Buchkovsky266f4902018-09-04 19:10:28 +03001491 return Py_BuildValue("II", navail, nleft);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001492 }
1493}
1494
Zachary Waref2244ea2015-05-13 01:22:54 -05001495/*[clinic input]
1496_winapi.ReadFile
1497
1498 handle: HANDLE
Alexander Buchkovsky266f4902018-09-04 19:10:28 +03001499 size: DWORD
Serhiy Storchaka202fda52017-03-12 10:10:47 +02001500 overlapped as use_overlapped: bool(accept={int}) = False
Zachary Waref2244ea2015-05-13 01:22:54 -05001501[clinic start generated code]*/
1502
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001503static PyObject *
Alexander Buchkovsky266f4902018-09-04 19:10:28 +03001504_winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size,
Zachary Ware77772c02015-05-13 10:58:35 -05001505 int use_overlapped)
Alexander Buchkovsky266f4902018-09-04 19:10:28 +03001506/*[clinic end generated code: output=d3d5b44a8201b944 input=08c439d03a11aac5]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001507{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001508 DWORD nread;
1509 PyObject *buf;
1510 BOOL ret;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001511 DWORD err;
1512 OverlappedObject *overlapped = NULL;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001513
1514 buf = PyBytes_FromStringAndSize(NULL, size);
1515 if (!buf)
1516 return NULL;
1517 if (use_overlapped) {
1518 overlapped = new_overlapped(handle);
1519 if (!overlapped) {
1520 Py_DECREF(buf);
1521 return NULL;
1522 }
1523 /* Steals reference to buf */
1524 overlapped->read_buffer = buf;
1525 }
1526
1527 Py_BEGIN_ALLOW_THREADS
1528 ret = ReadFile(handle, PyBytes_AS_STRING(buf), size, &nread,
1529 overlapped ? &overlapped->overlapped : NULL);
1530 Py_END_ALLOW_THREADS
1531
1532 err = ret ? 0 : GetLastError();
1533
1534 if (overlapped) {
1535 if (!ret) {
1536 if (err == ERROR_IO_PENDING)
1537 overlapped->pending = 1;
1538 else if (err != ERROR_MORE_DATA) {
1539 Py_DECREF(overlapped);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001540 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001541 }
1542 }
1543 return Py_BuildValue("NI", (PyObject *) overlapped, err);
1544 }
1545
1546 if (!ret && err != ERROR_MORE_DATA) {
1547 Py_DECREF(buf);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001548 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001549 }
1550 if (_PyBytes_Resize(&buf, nread))
1551 return NULL;
1552 return Py_BuildValue("NI", buf, err);
1553}
1554
Zachary Waref2244ea2015-05-13 01:22:54 -05001555/*[clinic input]
1556_winapi.SetNamedPipeHandleState
1557
1558 named_pipe: HANDLE
1559 mode: object
1560 max_collection_count: object
1561 collect_data_timeout: object
1562 /
1563[clinic start generated code]*/
1564
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001566_winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe,
Zachary Ware77772c02015-05-13 10:58:35 -05001567 PyObject *mode,
1568 PyObject *max_collection_count,
1569 PyObject *collect_data_timeout)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001570/*[clinic end generated code: output=f2129d222cbfa095 input=9142d72163d0faa6]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001571{
Zachary Waref2244ea2015-05-13 01:22:54 -05001572 PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout};
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001573 DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
1574 int i;
Steve Dowerb82e17e2019-05-23 08:45:22 -07001575 BOOL b;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001576
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001577 for (i = 0 ; i < 3 ; i++) {
1578 if (oArgs[i] != Py_None) {
1579 dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
1580 if (PyErr_Occurred())
1581 return NULL;
1582 pArgs[i] = &dwArgs[i];
1583 }
1584 }
1585
Steve Dowerb82e17e2019-05-23 08:45:22 -07001586 Py_BEGIN_ALLOW_THREADS
1587 b = SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2]);
1588 Py_END_ALLOW_THREADS
1589
1590 if (!b)
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001591 return PyErr_SetFromWindowsErr(0);
1592
1593 Py_RETURN_NONE;
1594}
1595
Zachary Waref2244ea2015-05-13 01:22:54 -05001596
1597/*[clinic input]
1598_winapi.TerminateProcess
1599
1600 handle: HANDLE
1601 exit_code: UINT
1602 /
1603
1604Terminate the specified process and all of its threads.
1605[clinic start generated code]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001606
1607static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001608_winapi_TerminateProcess_impl(PyObject *module, HANDLE handle,
Zachary Ware77772c02015-05-13 10:58:35 -05001609 UINT exit_code)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001610/*[clinic end generated code: output=f4e99ac3f0b1f34a input=d6bc0aa1ee3bb4df]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001611{
1612 BOOL result;
1613
Steve Dowerb82e17e2019-05-23 08:45:22 -07001614 if (PySys_Audit("_winapi.TerminateProcess", "nI",
1615 (Py_ssize_t)handle, exit_code) < 0) {
1616 return NULL;
1617 }
1618
Zachary Waref2244ea2015-05-13 01:22:54 -05001619 result = TerminateProcess(handle, exit_code);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001620
1621 if (! result)
1622 return PyErr_SetFromWindowsErr(GetLastError());
1623
Zachary Waref2244ea2015-05-13 01:22:54 -05001624 Py_RETURN_NONE;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001625}
1626
Zachary Waref2244ea2015-05-13 01:22:54 -05001627/*[clinic input]
Davin Pottse895de32019-02-23 22:08:16 -06001628_winapi.VirtualQuerySize -> size_t
1629
1630 address: LPCVOID
1631 /
1632[clinic start generated code]*/
1633
1634static size_t
1635_winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address)
1636/*[clinic end generated code: output=40c8e0ff5ec964df input=6b784a69755d0bb6]*/
1637{
1638 SIZE_T size_of_buf;
1639 MEMORY_BASIC_INFORMATION mem_basic_info;
1640 SIZE_T region_size;
1641
1642 Py_BEGIN_ALLOW_THREADS
1643 size_of_buf = VirtualQuery(address, &mem_basic_info, sizeof(mem_basic_info));
1644 Py_END_ALLOW_THREADS
1645
1646 if (size_of_buf == 0)
1647 PyErr_SetFromWindowsErr(0);
1648
1649 region_size = mem_basic_info.RegionSize;
1650 return region_size;
1651}
1652
1653/*[clinic input]
Zachary Waref2244ea2015-05-13 01:22:54 -05001654_winapi.WaitNamedPipe
1655
1656 name: LPCTSTR
1657 timeout: DWORD
1658 /
1659[clinic start generated code]*/
1660
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001662_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout)
1663/*[clinic end generated code: output=c2866f4439b1fe38 input=36fc781291b1862c]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001664{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001665 BOOL success;
1666
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001667 Py_BEGIN_ALLOW_THREADS
Zachary Waref2244ea2015-05-13 01:22:54 -05001668 success = WaitNamedPipe(name, timeout);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001669 Py_END_ALLOW_THREADS
1670
1671 if (!success)
1672 return PyErr_SetFromWindowsErr(0);
1673
1674 Py_RETURN_NONE;
1675}
1676
Zachary Waref2244ea2015-05-13 01:22:54 -05001677/*[clinic input]
1678_winapi.WaitForMultipleObjects
1679
1680 handle_seq: object
1681 wait_flag: BOOL
1682 milliseconds: DWORD(c_default='INFINITE') = _winapi.INFINITE
1683 /
1684[clinic start generated code]*/
1685
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001686static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001687_winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq,
1688 BOOL wait_flag, DWORD milliseconds)
1689/*[clinic end generated code: output=295e3f00b8e45899 input=36f76ca057cd28a0]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001690{
1691 DWORD result;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001692 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
1693 HANDLE sigint_event = NULL;
1694 Py_ssize_t nhandles, i;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001695
1696 if (!PySequence_Check(handle_seq)) {
1697 PyErr_Format(PyExc_TypeError,
1698 "sequence type expected, got '%s'",
Richard Oudkerk67339272012-08-21 14:54:22 +01001699 Py_TYPE(handle_seq)->tp_name);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001700 return NULL;
1701 }
1702 nhandles = PySequence_Length(handle_seq);
1703 if (nhandles == -1)
1704 return NULL;
1705 if (nhandles < 0 || nhandles >= MAXIMUM_WAIT_OBJECTS - 1) {
1706 PyErr_Format(PyExc_ValueError,
1707 "need at most %zd handles, got a sequence of length %zd",
1708 MAXIMUM_WAIT_OBJECTS - 1, nhandles);
1709 return NULL;
1710 }
1711 for (i = 0; i < nhandles; i++) {
1712 HANDLE h;
1713 PyObject *v = PySequence_GetItem(handle_seq, i);
1714 if (v == NULL)
1715 return NULL;
1716 if (!PyArg_Parse(v, F_HANDLE, &h)) {
1717 Py_DECREF(v);
1718 return NULL;
1719 }
1720 handles[i] = h;
1721 Py_DECREF(v);
1722 }
1723 /* If this is the main thread then make the wait interruptible
1724 by Ctrl-C unless we are waiting for *all* handles */
1725 if (!wait_flag && _PyOS_IsMainThread()) {
1726 sigint_event = _PyOS_SigintEvent();
1727 assert(sigint_event != NULL);
1728 handles[nhandles++] = sigint_event;
1729 }
1730
1731 Py_BEGIN_ALLOW_THREADS
1732 if (sigint_event != NULL)
1733 ResetEvent(sigint_event);
1734 result = WaitForMultipleObjects((DWORD) nhandles, handles,
1735 wait_flag, milliseconds);
1736 Py_END_ALLOW_THREADS
1737
1738 if (result == WAIT_FAILED)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001739 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001740 else if (sigint_event != NULL && result == WAIT_OBJECT_0 + nhandles - 1) {
1741 errno = EINTR;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001742 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001743 }
1744
1745 return PyLong_FromLong((int) result);
1746}
1747
Zachary Waref2244ea2015-05-13 01:22:54 -05001748/*[clinic input]
1749_winapi.WaitForSingleObject -> long
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001750
Zachary Waref2244ea2015-05-13 01:22:54 -05001751 handle: HANDLE
1752 milliseconds: DWORD
1753 /
1754
1755Wait for a single object.
1756
1757Wait until the specified object is in the signaled state or
1758the time-out interval elapses. The timeout value is specified
1759in milliseconds.
1760[clinic start generated code]*/
1761
1762static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001763_winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle,
Zachary Ware77772c02015-05-13 10:58:35 -05001764 DWORD milliseconds)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001765/*[clinic end generated code: output=3c4715d8f1b39859 input=443d1ab076edc7b1]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001766{
1767 DWORD result;
1768
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001769 Py_BEGIN_ALLOW_THREADS
1770 result = WaitForSingleObject(handle, milliseconds);
1771 Py_END_ALLOW_THREADS
1772
Zachary Waref2244ea2015-05-13 01:22:54 -05001773 if (result == WAIT_FAILED) {
1774 PyErr_SetFromWindowsErr(GetLastError());
1775 return -1;
1776 }
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001777
Zachary Waref2244ea2015-05-13 01:22:54 -05001778 return result;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001779}
1780
Zachary Waref2244ea2015-05-13 01:22:54 -05001781/*[clinic input]
1782_winapi.WriteFile
1783
1784 handle: HANDLE
1785 buffer: object
Serhiy Storchaka202fda52017-03-12 10:10:47 +02001786 overlapped as use_overlapped: bool(accept={int}) = False
Zachary Waref2244ea2015-05-13 01:22:54 -05001787[clinic start generated code]*/
1788
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001790_winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer,
Zachary Ware77772c02015-05-13 10:58:35 -05001791 int use_overlapped)
Serhiy Storchaka202fda52017-03-12 10:10:47 +02001792/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=11eae2a03aa32731]*/
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001793{
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001794 Py_buffer _buf, *buf;
Victor Stinner71765772013-06-24 23:13:24 +02001795 DWORD len, written;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001796 BOOL ret;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001797 DWORD err;
1798 OverlappedObject *overlapped = NULL;
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001799
1800 if (use_overlapped) {
1801 overlapped = new_overlapped(handle);
1802 if (!overlapped)
1803 return NULL;
1804 buf = &overlapped->write_buffer;
1805 }
1806 else
1807 buf = &_buf;
1808
Zachary Waref2244ea2015-05-13 01:22:54 -05001809 if (!PyArg_Parse(buffer, "y*", buf)) {
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001810 Py_XDECREF(overlapped);
1811 return NULL;
1812 }
1813
1814 Py_BEGIN_ALLOW_THREADS
Victor Stinner850a18e2017-10-24 16:53:32 -07001815 len = (DWORD)Py_MIN(buf->len, PY_DWORD_MAX);
Victor Stinner71765772013-06-24 23:13:24 +02001816 ret = WriteFile(handle, buf->buf, len, &written,
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001817 overlapped ? &overlapped->overlapped : NULL);
1818 Py_END_ALLOW_THREADS
1819
1820 err = ret ? 0 : GetLastError();
1821
1822 if (overlapped) {
1823 if (!ret) {
1824 if (err == ERROR_IO_PENDING)
1825 overlapped->pending = 1;
1826 else {
1827 Py_DECREF(overlapped);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001828 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001829 }
1830 }
1831 return Py_BuildValue("NI", (PyObject *) overlapped, err);
1832 }
1833
1834 PyBuffer_Release(buf);
1835 if (!ret)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001836 return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001837 return Py_BuildValue("II", written, err);
1838}
1839
Victor Stinner91106cd2017-12-13 12:29:09 +01001840/*[clinic input]
1841_winapi.GetACP
1842
1843Get the current Windows ANSI code page identifier.
1844[clinic start generated code]*/
1845
1846static PyObject *
1847_winapi_GetACP_impl(PyObject *module)
1848/*[clinic end generated code: output=f7ee24bf705dbb88 input=1433c96d03a05229]*/
1849{
1850 return PyLong_FromUnsignedLong(GetACP());
1851}
1852
Segev Finerb2a60832017-12-18 11:28:19 +02001853/*[clinic input]
1854_winapi.GetFileType -> DWORD
1855
1856 handle: HANDLE
1857[clinic start generated code]*/
1858
1859static DWORD
1860_winapi_GetFileType_impl(PyObject *module, HANDLE handle)
1861/*[clinic end generated code: output=92b8466ac76ecc17 input=0058366bc40bbfbf]*/
1862{
1863 DWORD result;
1864
1865 Py_BEGIN_ALLOW_THREADS
1866 result = GetFileType(handle);
1867 Py_END_ALLOW_THREADS
1868
1869 if (result == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR) {
1870 PyErr_SetFromWindowsErr(0);
1871 return -1;
1872 }
1873
1874 return result;
1875}
1876
Victor Stinner91106cd2017-12-13 12:29:09 +01001877
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001878static PyMethodDef winapi_functions[] = {
Zachary Waref2244ea2015-05-13 01:22:54 -05001879 _WINAPI_CLOSEHANDLE_METHODDEF
1880 _WINAPI_CONNECTNAMEDPIPE_METHODDEF
1881 _WINAPI_CREATEFILE_METHODDEF
Davin Pottse895de32019-02-23 22:08:16 -06001882 _WINAPI_CREATEFILEMAPPING_METHODDEF
Zachary Waref2244ea2015-05-13 01:22:54 -05001883 _WINAPI_CREATENAMEDPIPE_METHODDEF
1884 _WINAPI_CREATEPIPE_METHODDEF
1885 _WINAPI_CREATEPROCESS_METHODDEF
1886 _WINAPI_CREATEJUNCTION_METHODDEF
1887 _WINAPI_DUPLICATEHANDLE_METHODDEF
1888 _WINAPI_EXITPROCESS_METHODDEF
1889 _WINAPI_GETCURRENTPROCESS_METHODDEF
1890 _WINAPI_GETEXITCODEPROCESS_METHODDEF
1891 _WINAPI_GETLASTERROR_METHODDEF
1892 _WINAPI_GETMODULEFILENAME_METHODDEF
1893 _WINAPI_GETSTDHANDLE_METHODDEF
1894 _WINAPI_GETVERSION_METHODDEF
Davin Pottse895de32019-02-23 22:08:16 -06001895 _WINAPI_MAPVIEWOFFILE_METHODDEF
1896 _WINAPI_OPENFILEMAPPING_METHODDEF
Zachary Waref2244ea2015-05-13 01:22:54 -05001897 _WINAPI_OPENPROCESS_METHODDEF
1898 _WINAPI_PEEKNAMEDPIPE_METHODDEF
1899 _WINAPI_READFILE_METHODDEF
1900 _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF
1901 _WINAPI_TERMINATEPROCESS_METHODDEF
Davin Pottse895de32019-02-23 22:08:16 -06001902 _WINAPI_VIRTUALQUERYSIZE_METHODDEF
Zachary Waref2244ea2015-05-13 01:22:54 -05001903 _WINAPI_WAITNAMEDPIPE_METHODDEF
1904 _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF
1905 _WINAPI_WAITFORSINGLEOBJECT_METHODDEF
1906 _WINAPI_WRITEFILE_METHODDEF
Victor Stinner91106cd2017-12-13 12:29:09 +01001907 _WINAPI_GETACP_METHODDEF
Segev Finerb2a60832017-12-18 11:28:19 +02001908 _WINAPI_GETFILETYPE_METHODDEF
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001909 {NULL, NULL}
1910};
1911
1912static struct PyModuleDef winapi_module = {
1913 PyModuleDef_HEAD_INIT,
1914 "_winapi",
1915 NULL,
1916 -1,
1917 winapi_functions,
1918 NULL,
1919 NULL,
1920 NULL,
1921 NULL
1922};
1923
1924#define WINAPI_CONSTANT(fmt, con) \
1925 PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con))
1926
1927PyMODINIT_FUNC
1928PyInit__winapi(void)
1929{
1930 PyObject *d;
1931 PyObject *m;
1932
1933 if (PyType_Ready(&OverlappedType) < 0)
1934 return NULL;
1935
1936 m = PyModule_Create(&winapi_module);
1937 if (m == NULL)
1938 return NULL;
1939 d = PyModule_GetDict(m);
1940
1941 PyDict_SetItemString(d, "Overlapped", (PyObject *) &OverlappedType);
1942
1943 /* constants */
1944 WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE);
1945 WINAPI_CONSTANT(F_DWORD, CREATE_NEW_PROCESS_GROUP);
1946 WINAPI_CONSTANT(F_DWORD, DUPLICATE_SAME_ACCESS);
Antoine Pitrou5438ed12012-04-24 22:56:57 +02001947 WINAPI_CONSTANT(F_DWORD, DUPLICATE_CLOSE_SOURCE);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001948 WINAPI_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
1949 WINAPI_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE);
1950 WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
1951 WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA);
1952 WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
1953 WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001954 WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA);
1955 WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
Richard Oudkerkfdb8dcf2012-05-05 19:45:37 +01001956 WINAPI_CONSTANT(F_DWORD, ERROR_NO_DATA);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001957 WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES);
1958 WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED);
1959 WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
1960 WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
1961 WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
1962 WINAPI_CONSTANT(F_DWORD, FILE_FLAG_FIRST_PIPE_INSTANCE);
1963 WINAPI_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED);
Antoine Pitrou5438ed12012-04-24 22:56:57 +02001964 WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_READ);
1965 WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_WRITE);
Davin Pottse895de32019-02-23 22:08:16 -06001966 WINAPI_CONSTANT(F_DWORD, FILE_MAP_ALL_ACCESS);
1967 WINAPI_CONSTANT(F_DWORD, FILE_MAP_COPY);
1968 WINAPI_CONSTANT(F_DWORD, FILE_MAP_EXECUTE);
1969 WINAPI_CONSTANT(F_DWORD, FILE_MAP_READ);
1970 WINAPI_CONSTANT(F_DWORD, FILE_MAP_WRITE);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001971 WINAPI_CONSTANT(F_DWORD, GENERIC_READ);
1972 WINAPI_CONSTANT(F_DWORD, GENERIC_WRITE);
1973 WINAPI_CONSTANT(F_DWORD, INFINITE);
Davin Pottse895de32019-02-23 22:08:16 -06001974 WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE);
1975 WINAPI_CONSTANT(F_DWORD, MEM_COMMIT);
1976 WINAPI_CONSTANT(F_DWORD, MEM_FREE);
1977 WINAPI_CONSTANT(F_DWORD, MEM_IMAGE);
1978 WINAPI_CONSTANT(F_DWORD, MEM_MAPPED);
1979 WINAPI_CONSTANT(F_DWORD, MEM_PRIVATE);
1980 WINAPI_CONSTANT(F_DWORD, MEM_RESERVE);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001981 WINAPI_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
1982 WINAPI_CONSTANT(F_DWORD, OPEN_EXISTING);
Davin Pottse895de32019-02-23 22:08:16 -06001983 WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE);
1984 WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READ);
1985 WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READWRITE);
1986 WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_WRITECOPY);
1987 WINAPI_CONSTANT(F_DWORD, PAGE_GUARD);
1988 WINAPI_CONSTANT(F_DWORD, PAGE_NOACCESS);
1989 WINAPI_CONSTANT(F_DWORD, PAGE_NOCACHE);
1990 WINAPI_CONSTANT(F_DWORD, PAGE_READONLY);
1991 WINAPI_CONSTANT(F_DWORD, PAGE_READWRITE);
1992 WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOMBINE);
1993 WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOPY);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02001994 WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
1995 WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
1996 WINAPI_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
1997 WINAPI_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
1998 WINAPI_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
1999 WINAPI_CONSTANT(F_DWORD, PIPE_WAIT);
2000 WINAPI_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
Thomas Moreauc09a9f52019-05-20 21:37:05 +02002001 WINAPI_CONSTANT(F_DWORD, SYNCHRONIZE);
Antoine Pitrou5438ed12012-04-24 22:56:57 +02002002 WINAPI_CONSTANT(F_DWORD, PROCESS_DUP_HANDLE);
Davin Pottse895de32019-02-23 22:08:16 -06002003 WINAPI_CONSTANT(F_DWORD, SEC_COMMIT);
2004 WINAPI_CONSTANT(F_DWORD, SEC_IMAGE);
2005 WINAPI_CONSTANT(F_DWORD, SEC_LARGE_PAGES);
2006 WINAPI_CONSTANT(F_DWORD, SEC_NOCACHE);
2007 WINAPI_CONSTANT(F_DWORD, SEC_RESERVE);
2008 WINAPI_CONSTANT(F_DWORD, SEC_WRITECOMBINE);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02002009 WINAPI_CONSTANT(F_DWORD, STARTF_USESHOWWINDOW);
2010 WINAPI_CONSTANT(F_DWORD, STARTF_USESTDHANDLES);
2011 WINAPI_CONSTANT(F_DWORD, STD_INPUT_HANDLE);
2012 WINAPI_CONSTANT(F_DWORD, STD_OUTPUT_HANDLE);
2013 WINAPI_CONSTANT(F_DWORD, STD_ERROR_HANDLE);
2014 WINAPI_CONSTANT(F_DWORD, STILL_ACTIVE);
2015 WINAPI_CONSTANT(F_DWORD, SW_HIDE);
2016 WINAPI_CONSTANT(F_DWORD, WAIT_OBJECT_0);
Victor Stinner373f0a92014-03-20 09:26:55 +01002017 WINAPI_CONSTANT(F_DWORD, WAIT_ABANDONED_0);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02002018 WINAPI_CONSTANT(F_DWORD, WAIT_TIMEOUT);
Victor Stinner91106cd2017-12-13 12:29:09 +01002019
Jamesb5d9e082017-11-08 14:18:59 +00002020 WINAPI_CONSTANT(F_DWORD, ABOVE_NORMAL_PRIORITY_CLASS);
2021 WINAPI_CONSTANT(F_DWORD, BELOW_NORMAL_PRIORITY_CLASS);
2022 WINAPI_CONSTANT(F_DWORD, HIGH_PRIORITY_CLASS);
2023 WINAPI_CONSTANT(F_DWORD, IDLE_PRIORITY_CLASS);
2024 WINAPI_CONSTANT(F_DWORD, NORMAL_PRIORITY_CLASS);
2025 WINAPI_CONSTANT(F_DWORD, REALTIME_PRIORITY_CLASS);
Victor Stinner91106cd2017-12-13 12:29:09 +01002026
Jamesb5d9e082017-11-08 14:18:59 +00002027 WINAPI_CONSTANT(F_DWORD, CREATE_NO_WINDOW);
2028 WINAPI_CONSTANT(F_DWORD, DETACHED_PROCESS);
2029 WINAPI_CONSTANT(F_DWORD, CREATE_DEFAULT_ERROR_MODE);
2030 WINAPI_CONSTANT(F_DWORD, CREATE_BREAKAWAY_FROM_JOB);
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02002031
Segev Finerb2a60832017-12-18 11:28:19 +02002032 WINAPI_CONSTANT(F_DWORD, FILE_TYPE_UNKNOWN);
2033 WINAPI_CONSTANT(F_DWORD, FILE_TYPE_DISK);
2034 WINAPI_CONSTANT(F_DWORD, FILE_TYPE_CHAR);
2035 WINAPI_CONSTANT(F_DWORD, FILE_TYPE_PIPE);
2036 WINAPI_CONSTANT(F_DWORD, FILE_TYPE_REMOTE);
2037
Antoine Pitrou23bba4c2012-04-18 20:51:15 +02002038 WINAPI_CONSTANT("i", NULL);
2039
2040 return m;
2041}