17db96d56Sopenharmony_ci/*
27db96d56Sopenharmony_ci * Support routines from the Windows API
37db96d56Sopenharmony_ci *
47db96d56Sopenharmony_ci * This module was originally created by merging PC/_subprocess.c with
57db96d56Sopenharmony_ci * Modules/_multiprocessing/win32_functions.c.
67db96d56Sopenharmony_ci *
77db96d56Sopenharmony_ci * Copyright (c) 2004 by Fredrik Lundh <fredrik@pythonware.com>
87db96d56Sopenharmony_ci * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com
97db96d56Sopenharmony_ci * Copyright (c) 2004 by Peter Astrand <astrand@lysator.liu.se>
107db96d56Sopenharmony_ci *
117db96d56Sopenharmony_ci * By obtaining, using, and/or copying this software and/or its
127db96d56Sopenharmony_ci * associated documentation, you agree that you have read, understood,
137db96d56Sopenharmony_ci * and will comply with the following terms and conditions:
147db96d56Sopenharmony_ci *
157db96d56Sopenharmony_ci * Permission to use, copy, modify, and distribute this software and
167db96d56Sopenharmony_ci * its associated documentation for any purpose and without fee is
177db96d56Sopenharmony_ci * hereby granted, provided that the above copyright notice appears in
187db96d56Sopenharmony_ci * all copies, and that both that copyright notice and this permission
197db96d56Sopenharmony_ci * notice appear in supporting documentation, and that the name of the
207db96d56Sopenharmony_ci * authors not be used in advertising or publicity pertaining to
217db96d56Sopenharmony_ci * distribution of the software without specific, written prior
227db96d56Sopenharmony_ci * permission.
237db96d56Sopenharmony_ci *
247db96d56Sopenharmony_ci * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
257db96d56Sopenharmony_ci * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
267db96d56Sopenharmony_ci * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
277db96d56Sopenharmony_ci * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
287db96d56Sopenharmony_ci * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
297db96d56Sopenharmony_ci * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
307db96d56Sopenharmony_ci * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
317db96d56Sopenharmony_ci *
327db96d56Sopenharmony_ci */
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ci/* Licensed to PSF under a Contributor Agreement. */
357db96d56Sopenharmony_ci/* See https://www.python.org/2.4/license for licensing details. */
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci#include "Python.h"
387db96d56Sopenharmony_ci#include "pycore_moduleobject.h"  // _PyModule_GetState()
397db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_ci#define WINDOWS_LEAN_AND_MEAN
437db96d56Sopenharmony_ci#include "windows.h"
447db96d56Sopenharmony_ci#include <crtdbg.h>
457db96d56Sopenharmony_ci#include "winreparse.h"
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci#if defined(MS_WIN32) && !defined(MS_WIN64)
487db96d56Sopenharmony_ci#define HANDLE_TO_PYNUM(handle) \
497db96d56Sopenharmony_ci    PyLong_FromUnsignedLong((unsigned long) handle)
507db96d56Sopenharmony_ci#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLong(obj))
517db96d56Sopenharmony_ci#define F_POINTER "k"
527db96d56Sopenharmony_ci#define T_POINTER T_ULONG
537db96d56Sopenharmony_ci#else
547db96d56Sopenharmony_ci#define HANDLE_TO_PYNUM(handle) \
557db96d56Sopenharmony_ci    PyLong_FromUnsignedLongLong((unsigned long long) handle)
567db96d56Sopenharmony_ci#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLongLong(obj))
577db96d56Sopenharmony_ci#define F_POINTER "K"
587db96d56Sopenharmony_ci#define T_POINTER T_ULONGLONG
597db96d56Sopenharmony_ci#endif
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci#define F_HANDLE F_POINTER
627db96d56Sopenharmony_ci#define F_DWORD "k"
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci#define T_HANDLE T_POINTER
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci/* Grab CancelIoEx dynamically from kernel32 */
677db96d56Sopenharmony_cistatic int has_CancelIoEx = -1;
687db96d56Sopenharmony_cistatic BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED);
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_cistatic int
717db96d56Sopenharmony_cicheck_CancelIoEx()
727db96d56Sopenharmony_ci{
737db96d56Sopenharmony_ci    if (has_CancelIoEx == -1)
747db96d56Sopenharmony_ci    {
757db96d56Sopenharmony_ci        HINSTANCE hKernel32 = GetModuleHandle("KERNEL32");
767db96d56Sopenharmony_ci        * (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32,
777db96d56Sopenharmony_ci                                                      "CancelIoEx");
787db96d56Sopenharmony_ci        has_CancelIoEx = (Py_CancelIoEx != NULL);
797db96d56Sopenharmony_ci    }
807db96d56Sopenharmony_ci    return has_CancelIoEx;
817db96d56Sopenharmony_ci}
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_citypedef struct {
847db96d56Sopenharmony_ci    PyTypeObject *overlapped_type;
857db96d56Sopenharmony_ci} WinApiState;
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_cistatic inline WinApiState*
887db96d56Sopenharmony_ciwinapi_get_state(PyObject *module)
897db96d56Sopenharmony_ci{
907db96d56Sopenharmony_ci    void *state = _PyModule_GetState(module);
917db96d56Sopenharmony_ci    assert(state != NULL);
927db96d56Sopenharmony_ci    return (WinApiState *)state;
937db96d56Sopenharmony_ci}
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci/*
967db96d56Sopenharmony_ci * A Python object wrapping an OVERLAPPED structure and other useful data
977db96d56Sopenharmony_ci * for overlapped I/O
987db96d56Sopenharmony_ci */
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_citypedef struct {
1017db96d56Sopenharmony_ci    PyObject_HEAD
1027db96d56Sopenharmony_ci    OVERLAPPED overlapped;
1037db96d56Sopenharmony_ci    /* For convenience, we store the file handle too */
1047db96d56Sopenharmony_ci    HANDLE handle;
1057db96d56Sopenharmony_ci    /* Whether there's I/O in flight */
1067db96d56Sopenharmony_ci    int pending;
1077db96d56Sopenharmony_ci    /* Whether I/O completed successfully */
1087db96d56Sopenharmony_ci    int completed;
1097db96d56Sopenharmony_ci    /* Buffer used for reading (optional) */
1107db96d56Sopenharmony_ci    PyObject *read_buffer;
1117db96d56Sopenharmony_ci    /* Buffer used for writing (optional) */
1127db96d56Sopenharmony_ci    Py_buffer write_buffer;
1137db96d56Sopenharmony_ci} OverlappedObject;
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci/*
1167db96d56Sopenharmony_ciNote: tp_clear (overlapped_clear) is not implemented because it
1177db96d56Sopenharmony_cirequires cancelling the IO operation if it's pending and the cancellation is
1187db96d56Sopenharmony_ciquite complex and can fail (see: overlapped_dealloc).
1197db96d56Sopenharmony_ci*/
1207db96d56Sopenharmony_cistatic int
1217db96d56Sopenharmony_cioverlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
1227db96d56Sopenharmony_ci{
1237db96d56Sopenharmony_ci    Py_VISIT(self->read_buffer);
1247db96d56Sopenharmony_ci    Py_VISIT(self->write_buffer.obj);
1257db96d56Sopenharmony_ci    Py_VISIT(Py_TYPE(self));
1267db96d56Sopenharmony_ci    return 0;
1277db96d56Sopenharmony_ci}
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_cistatic void
1307db96d56Sopenharmony_cioverlapped_dealloc(OverlappedObject *self)
1317db96d56Sopenharmony_ci{
1327db96d56Sopenharmony_ci    DWORD bytes;
1337db96d56Sopenharmony_ci    int err = GetLastError();
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci    PyObject_GC_UnTrack(self);
1367db96d56Sopenharmony_ci    if (self->pending) {
1377db96d56Sopenharmony_ci        if (check_CancelIoEx() &&
1387db96d56Sopenharmony_ci            Py_CancelIoEx(self->handle, &self->overlapped) &&
1397db96d56Sopenharmony_ci            GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE))
1407db96d56Sopenharmony_ci        {
1417db96d56Sopenharmony_ci            /* The operation is no longer pending -- nothing to do. */
1427db96d56Sopenharmony_ci        }
1437db96d56Sopenharmony_ci        else if (_Py_IsFinalizing())
1447db96d56Sopenharmony_ci        {
1457db96d56Sopenharmony_ci            /* The operation is still pending -- give a warning.  This
1467db96d56Sopenharmony_ci               will probably only happen on Windows XP. */
1477db96d56Sopenharmony_ci            PyErr_SetString(PyExc_RuntimeError,
1487db96d56Sopenharmony_ci                            "I/O operations still in flight while destroying "
1497db96d56Sopenharmony_ci                            "Overlapped object, the process may crash");
1507db96d56Sopenharmony_ci            PyErr_WriteUnraisable(NULL);
1517db96d56Sopenharmony_ci        }
1527db96d56Sopenharmony_ci        else
1537db96d56Sopenharmony_ci        {
1547db96d56Sopenharmony_ci            /* The operation is still pending, but the process is
1557db96d56Sopenharmony_ci               probably about to exit, so we need not worry too much
1567db96d56Sopenharmony_ci               about memory leaks.  Leaking self prevents a potential
1577db96d56Sopenharmony_ci               crash.  This can happen when a daemon thread is cleaned
1587db96d56Sopenharmony_ci               up at exit -- see #19565.  We only expect to get here
1597db96d56Sopenharmony_ci               on Windows XP. */
1607db96d56Sopenharmony_ci            CloseHandle(self->overlapped.hEvent);
1617db96d56Sopenharmony_ci            SetLastError(err);
1627db96d56Sopenharmony_ci            return;
1637db96d56Sopenharmony_ci        }
1647db96d56Sopenharmony_ci    }
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ci    CloseHandle(self->overlapped.hEvent);
1677db96d56Sopenharmony_ci    SetLastError(err);
1687db96d56Sopenharmony_ci    if (self->write_buffer.obj)
1697db96d56Sopenharmony_ci        PyBuffer_Release(&self->write_buffer);
1707db96d56Sopenharmony_ci    Py_CLEAR(self->read_buffer);
1717db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(self);
1727db96d56Sopenharmony_ci    tp->tp_free(self);
1737db96d56Sopenharmony_ci    Py_DECREF(tp);
1747db96d56Sopenharmony_ci}
1757db96d56Sopenharmony_ci
1767db96d56Sopenharmony_ci/*[clinic input]
1777db96d56Sopenharmony_cimodule _winapi
1787db96d56Sopenharmony_ciclass _winapi.Overlapped "OverlappedObject *" "&OverlappedType"
1797db96d56Sopenharmony_ci[clinic start generated code]*/
1807db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c13d3f5fd1dabb84]*/
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci/*[python input]
1837db96d56Sopenharmony_cidef create_converter(type_, format_unit):
1847db96d56Sopenharmony_ci    name = type_ + '_converter'
1857db96d56Sopenharmony_ci    # registered upon creation by CConverter's metaclass
1867db96d56Sopenharmony_ci    type(name, (CConverter,), {'type': type_, 'format_unit': format_unit})
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ci# format unit differs between platforms for these
1897db96d56Sopenharmony_cicreate_converter('HANDLE', '" F_HANDLE "')
1907db96d56Sopenharmony_cicreate_converter('HMODULE', '" F_HANDLE "')
1917db96d56Sopenharmony_cicreate_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "')
1927db96d56Sopenharmony_cicreate_converter('LPCVOID', '" F_POINTER "')
1937db96d56Sopenharmony_ci
1947db96d56Sopenharmony_cicreate_converter('BOOL', 'i') # F_BOOL used previously (always 'i')
1957db96d56Sopenharmony_cicreate_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter)
1967db96d56Sopenharmony_cicreate_converter('LPCTSTR', 's')
1977db96d56Sopenharmony_cicreate_converter('UINT', 'I') # F_UINT used previously (always 'I')
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ciclass LPCWSTR_converter(Py_UNICODE_converter):
2007db96d56Sopenharmony_ci    type = 'LPCWSTR'
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ciclass HANDLE_return_converter(CReturnConverter):
2037db96d56Sopenharmony_ci    type = 'HANDLE'
2047db96d56Sopenharmony_ci
2057db96d56Sopenharmony_ci    def render(self, function, data):
2067db96d56Sopenharmony_ci        self.declare(data)
2077db96d56Sopenharmony_ci        self.err_occurred_if("_return_value == INVALID_HANDLE_VALUE", data)
2087db96d56Sopenharmony_ci        data.return_conversion.append(
2097db96d56Sopenharmony_ci            'if (_return_value == NULL) {\n    Py_RETURN_NONE;\n}\n')
2107db96d56Sopenharmony_ci        data.return_conversion.append(
2117db96d56Sopenharmony_ci            'return_value = HANDLE_TO_PYNUM(_return_value);\n')
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ciclass DWORD_return_converter(CReturnConverter):
2147db96d56Sopenharmony_ci    type = 'DWORD'
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ci    def render(self, function, data):
2177db96d56Sopenharmony_ci        self.declare(data)
2187db96d56Sopenharmony_ci        self.err_occurred_if("_return_value == PY_DWORD_MAX", data)
2197db96d56Sopenharmony_ci        data.return_conversion.append(
2207db96d56Sopenharmony_ci            'return_value = Py_BuildValue("k", _return_value);\n')
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ciclass LPVOID_return_converter(CReturnConverter):
2237db96d56Sopenharmony_ci    type = 'LPVOID'
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ci    def render(self, function, data):
2267db96d56Sopenharmony_ci        self.declare(data)
2277db96d56Sopenharmony_ci        self.err_occurred_if("_return_value == NULL", data)
2287db96d56Sopenharmony_ci        data.return_conversion.append(
2297db96d56Sopenharmony_ci            'return_value = HANDLE_TO_PYNUM(_return_value);\n')
2307db96d56Sopenharmony_ci[python start generated code]*/
2317db96d56Sopenharmony_ci/*[python end generated code: output=da39a3ee5e6b4b0d input=011ee0c3a2244bfe]*/
2327db96d56Sopenharmony_ci
2337db96d56Sopenharmony_ci#include "clinic/_winapi.c.h"
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci/*[clinic input]
2367db96d56Sopenharmony_ci_winapi.Overlapped.GetOverlappedResult
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ci    wait: bool
2397db96d56Sopenharmony_ci    /
2407db96d56Sopenharmony_ci[clinic start generated code]*/
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_cistatic PyObject *
2437db96d56Sopenharmony_ci_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait)
2447db96d56Sopenharmony_ci/*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/
2457db96d56Sopenharmony_ci{
2467db96d56Sopenharmony_ci    BOOL res;
2477db96d56Sopenharmony_ci    DWORD transferred = 0;
2487db96d56Sopenharmony_ci    DWORD err;
2497db96d56Sopenharmony_ci
2507db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
2517db96d56Sopenharmony_ci    res = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
2527db96d56Sopenharmony_ci                              wait != 0);
2537db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
2547db96d56Sopenharmony_ci
2557db96d56Sopenharmony_ci    err = res ? ERROR_SUCCESS : GetLastError();
2567db96d56Sopenharmony_ci    switch (err) {
2577db96d56Sopenharmony_ci        case ERROR_SUCCESS:
2587db96d56Sopenharmony_ci        case ERROR_MORE_DATA:
2597db96d56Sopenharmony_ci        case ERROR_OPERATION_ABORTED:
2607db96d56Sopenharmony_ci            self->completed = 1;
2617db96d56Sopenharmony_ci            self->pending = 0;
2627db96d56Sopenharmony_ci            break;
2637db96d56Sopenharmony_ci        case ERROR_IO_INCOMPLETE:
2647db96d56Sopenharmony_ci            break;
2657db96d56Sopenharmony_ci        default:
2667db96d56Sopenharmony_ci            self->pending = 0;
2677db96d56Sopenharmony_ci            return PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
2687db96d56Sopenharmony_ci    }
2697db96d56Sopenharmony_ci    if (self->completed && self->read_buffer != NULL) {
2707db96d56Sopenharmony_ci        assert(PyBytes_CheckExact(self->read_buffer));
2717db96d56Sopenharmony_ci        if (transferred != PyBytes_GET_SIZE(self->read_buffer) &&
2727db96d56Sopenharmony_ci            _PyBytes_Resize(&self->read_buffer, transferred))
2737db96d56Sopenharmony_ci            return NULL;
2747db96d56Sopenharmony_ci    }
2757db96d56Sopenharmony_ci    return Py_BuildValue("II", (unsigned) transferred, (unsigned) err);
2767db96d56Sopenharmony_ci}
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_ci/*[clinic input]
2797db96d56Sopenharmony_ci_winapi.Overlapped.getbuffer
2807db96d56Sopenharmony_ci[clinic start generated code]*/
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_cistatic PyObject *
2837db96d56Sopenharmony_ci_winapi_Overlapped_getbuffer_impl(OverlappedObject *self)
2847db96d56Sopenharmony_ci/*[clinic end generated code: output=95a3eceefae0f748 input=347fcfd56b4ceabd]*/
2857db96d56Sopenharmony_ci{
2867db96d56Sopenharmony_ci    PyObject *res;
2877db96d56Sopenharmony_ci    if (!self->completed) {
2887db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2897db96d56Sopenharmony_ci                        "can't get read buffer before GetOverlappedResult() "
2907db96d56Sopenharmony_ci                        "signals the operation completed");
2917db96d56Sopenharmony_ci        return NULL;
2927db96d56Sopenharmony_ci    }
2937db96d56Sopenharmony_ci    res = self->read_buffer ? self->read_buffer : Py_None;
2947db96d56Sopenharmony_ci    Py_INCREF(res);
2957db96d56Sopenharmony_ci    return res;
2967db96d56Sopenharmony_ci}
2977db96d56Sopenharmony_ci
2987db96d56Sopenharmony_ci/*[clinic input]
2997db96d56Sopenharmony_ci_winapi.Overlapped.cancel
3007db96d56Sopenharmony_ci[clinic start generated code]*/
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_cistatic PyObject *
3037db96d56Sopenharmony_ci_winapi_Overlapped_cancel_impl(OverlappedObject *self)
3047db96d56Sopenharmony_ci/*[clinic end generated code: output=fcb9ab5df4ebdae5 input=cbf3da142290039f]*/
3057db96d56Sopenharmony_ci{
3067db96d56Sopenharmony_ci    BOOL res = TRUE;
3077db96d56Sopenharmony_ci
3087db96d56Sopenharmony_ci    if (self->pending) {
3097db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
3107db96d56Sopenharmony_ci        if (check_CancelIoEx())
3117db96d56Sopenharmony_ci            res = Py_CancelIoEx(self->handle, &self->overlapped);
3127db96d56Sopenharmony_ci        else
3137db96d56Sopenharmony_ci            res = CancelIo(self->handle);
3147db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
3157db96d56Sopenharmony_ci    }
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_ci    /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */
3187db96d56Sopenharmony_ci    if (!res && GetLastError() != ERROR_NOT_FOUND)
3197db96d56Sopenharmony_ci        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
3207db96d56Sopenharmony_ci    self->pending = 0;
3217db96d56Sopenharmony_ci    Py_RETURN_NONE;
3227db96d56Sopenharmony_ci}
3237db96d56Sopenharmony_ci
3247db96d56Sopenharmony_cistatic PyMethodDef overlapped_methods[] = {
3257db96d56Sopenharmony_ci    _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF
3267db96d56Sopenharmony_ci    _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF
3277db96d56Sopenharmony_ci    _WINAPI_OVERLAPPED_CANCEL_METHODDEF
3287db96d56Sopenharmony_ci    {NULL}
3297db96d56Sopenharmony_ci};
3307db96d56Sopenharmony_ci
3317db96d56Sopenharmony_cistatic PyMemberDef overlapped_members[] = {
3327db96d56Sopenharmony_ci    {"event", T_HANDLE,
3337db96d56Sopenharmony_ci     offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
3347db96d56Sopenharmony_ci     READONLY, "overlapped event handle"},
3357db96d56Sopenharmony_ci    {NULL}
3367db96d56Sopenharmony_ci};
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_cistatic PyType_Slot winapi_overlapped_type_slots[] = {
3397db96d56Sopenharmony_ci    {Py_tp_traverse, overlapped_traverse},
3407db96d56Sopenharmony_ci    {Py_tp_dealloc, overlapped_dealloc},
3417db96d56Sopenharmony_ci    {Py_tp_doc, "OVERLAPPED structure wrapper"},
3427db96d56Sopenharmony_ci    {Py_tp_methods, overlapped_methods},
3437db96d56Sopenharmony_ci    {Py_tp_members, overlapped_members},
3447db96d56Sopenharmony_ci    {0,0}
3457db96d56Sopenharmony_ci};
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_cistatic PyType_Spec winapi_overlapped_type_spec = {
3487db96d56Sopenharmony_ci    .name = "_winapi.Overlapped",
3497db96d56Sopenharmony_ci    .basicsize = sizeof(OverlappedObject),
3507db96d56Sopenharmony_ci    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
3517db96d56Sopenharmony_ci              Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
3527db96d56Sopenharmony_ci    .slots = winapi_overlapped_type_slots,
3537db96d56Sopenharmony_ci};
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_cistatic OverlappedObject *
3567db96d56Sopenharmony_cinew_overlapped(PyObject *module, HANDLE handle)
3577db96d56Sopenharmony_ci{
3587db96d56Sopenharmony_ci    WinApiState *st = winapi_get_state(module);
3597db96d56Sopenharmony_ci    OverlappedObject *self = PyObject_GC_New(OverlappedObject, st->overlapped_type);
3607db96d56Sopenharmony_ci    if (!self)
3617db96d56Sopenharmony_ci        return NULL;
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci    self->handle = handle;
3647db96d56Sopenharmony_ci    self->read_buffer = NULL;
3657db96d56Sopenharmony_ci    self->pending = 0;
3667db96d56Sopenharmony_ci    self->completed = 0;
3677db96d56Sopenharmony_ci    memset(&self->overlapped, 0, sizeof(OVERLAPPED));
3687db96d56Sopenharmony_ci    memset(&self->write_buffer, 0, sizeof(Py_buffer));
3697db96d56Sopenharmony_ci    /* Manual reset, initially non-signalled */
3707db96d56Sopenharmony_ci    self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
3717db96d56Sopenharmony_ci
3727db96d56Sopenharmony_ci    PyObject_GC_Track(self);
3737db96d56Sopenharmony_ci    return self;
3747db96d56Sopenharmony_ci}
3757db96d56Sopenharmony_ci
3767db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
3777db96d56Sopenharmony_ci/* windows API functions */
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci/*[clinic input]
3807db96d56Sopenharmony_ci_winapi.CloseHandle
3817db96d56Sopenharmony_ci
3827db96d56Sopenharmony_ci    handle: HANDLE
3837db96d56Sopenharmony_ci    /
3847db96d56Sopenharmony_ci
3857db96d56Sopenharmony_ciClose handle.
3867db96d56Sopenharmony_ci[clinic start generated code]*/
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_cistatic PyObject *
3897db96d56Sopenharmony_ci_winapi_CloseHandle_impl(PyObject *module, HANDLE handle)
3907db96d56Sopenharmony_ci/*[clinic end generated code: output=7ad37345f07bd782 input=7f0e4ac36e0352b8]*/
3917db96d56Sopenharmony_ci{
3927db96d56Sopenharmony_ci    BOOL success;
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
3957db96d56Sopenharmony_ci    success = CloseHandle(handle);
3967db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci    if (!success)
3997db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(0);
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_ci    Py_RETURN_NONE;
4027db96d56Sopenharmony_ci}
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_ci/*[clinic input]
4057db96d56Sopenharmony_ci_winapi.ConnectNamedPipe
4067db96d56Sopenharmony_ci
4077db96d56Sopenharmony_ci    handle: HANDLE
4087db96d56Sopenharmony_ci    overlapped as use_overlapped: bool(accept={int}) = False
4097db96d56Sopenharmony_ci[clinic start generated code]*/
4107db96d56Sopenharmony_ci
4117db96d56Sopenharmony_cistatic PyObject *
4127db96d56Sopenharmony_ci_winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
4137db96d56Sopenharmony_ci                              int use_overlapped)
4147db96d56Sopenharmony_ci/*[clinic end generated code: output=335a0e7086800671 input=34f937c1c86e5e68]*/
4157db96d56Sopenharmony_ci{
4167db96d56Sopenharmony_ci    BOOL success;
4177db96d56Sopenharmony_ci    OverlappedObject *overlapped = NULL;
4187db96d56Sopenharmony_ci
4197db96d56Sopenharmony_ci    if (use_overlapped) {
4207db96d56Sopenharmony_ci        overlapped = new_overlapped(module, handle);
4217db96d56Sopenharmony_ci        if (!overlapped)
4227db96d56Sopenharmony_ci            return NULL;
4237db96d56Sopenharmony_ci    }
4247db96d56Sopenharmony_ci
4257db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
4267db96d56Sopenharmony_ci    success = ConnectNamedPipe(handle,
4277db96d56Sopenharmony_ci                               overlapped ? &overlapped->overlapped : NULL);
4287db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
4297db96d56Sopenharmony_ci
4307db96d56Sopenharmony_ci    if (overlapped) {
4317db96d56Sopenharmony_ci        int err = GetLastError();
4327db96d56Sopenharmony_ci        /* Overlapped ConnectNamedPipe never returns a success code */
4337db96d56Sopenharmony_ci        assert(success == 0);
4347db96d56Sopenharmony_ci        if (err == ERROR_IO_PENDING)
4357db96d56Sopenharmony_ci            overlapped->pending = 1;
4367db96d56Sopenharmony_ci        else if (err == ERROR_PIPE_CONNECTED)
4377db96d56Sopenharmony_ci            SetEvent(overlapped->overlapped.hEvent);
4387db96d56Sopenharmony_ci        else {
4397db96d56Sopenharmony_ci            Py_DECREF(overlapped);
4407db96d56Sopenharmony_ci            return PyErr_SetFromWindowsErr(err);
4417db96d56Sopenharmony_ci        }
4427db96d56Sopenharmony_ci        return (PyObject *) overlapped;
4437db96d56Sopenharmony_ci    }
4447db96d56Sopenharmony_ci    if (!success)
4457db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(0);
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ci    Py_RETURN_NONE;
4487db96d56Sopenharmony_ci}
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ci/*[clinic input]
4517db96d56Sopenharmony_ci_winapi.CreateFile -> HANDLE
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci    file_name: LPCTSTR
4547db96d56Sopenharmony_ci    desired_access: DWORD
4557db96d56Sopenharmony_ci    share_mode: DWORD
4567db96d56Sopenharmony_ci    security_attributes: LPSECURITY_ATTRIBUTES
4577db96d56Sopenharmony_ci    creation_disposition: DWORD
4587db96d56Sopenharmony_ci    flags_and_attributes: DWORD
4597db96d56Sopenharmony_ci    template_file: HANDLE
4607db96d56Sopenharmony_ci    /
4617db96d56Sopenharmony_ci[clinic start generated code]*/
4627db96d56Sopenharmony_ci
4637db96d56Sopenharmony_cistatic HANDLE
4647db96d56Sopenharmony_ci_winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name,
4657db96d56Sopenharmony_ci                        DWORD desired_access, DWORD share_mode,
4667db96d56Sopenharmony_ci                        LPSECURITY_ATTRIBUTES security_attributes,
4677db96d56Sopenharmony_ci                        DWORD creation_disposition,
4687db96d56Sopenharmony_ci                        DWORD flags_and_attributes, HANDLE template_file)
4697db96d56Sopenharmony_ci/*[clinic end generated code: output=417ddcebfc5a3d53 input=6423c3e40372dbd5]*/
4707db96d56Sopenharmony_ci{
4717db96d56Sopenharmony_ci    HANDLE handle;
4727db96d56Sopenharmony_ci
4737db96d56Sopenharmony_ci    if (PySys_Audit("_winapi.CreateFile", "uIIII",
4747db96d56Sopenharmony_ci                    file_name, desired_access, share_mode,
4757db96d56Sopenharmony_ci                    creation_disposition, flags_and_attributes) < 0) {
4767db96d56Sopenharmony_ci        return INVALID_HANDLE_VALUE;
4777db96d56Sopenharmony_ci    }
4787db96d56Sopenharmony_ci
4797db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
4807db96d56Sopenharmony_ci    handle = CreateFile(file_name, desired_access,
4817db96d56Sopenharmony_ci                        share_mode, security_attributes,
4827db96d56Sopenharmony_ci                        creation_disposition,
4837db96d56Sopenharmony_ci                        flags_and_attributes, template_file);
4847db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
4857db96d56Sopenharmony_ci
4867db96d56Sopenharmony_ci    if (handle == INVALID_HANDLE_VALUE)
4877db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(0);
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci    return handle;
4907db96d56Sopenharmony_ci}
4917db96d56Sopenharmony_ci
4927db96d56Sopenharmony_ci/*[clinic input]
4937db96d56Sopenharmony_ci_winapi.CreateFileMapping -> HANDLE
4947db96d56Sopenharmony_ci
4957db96d56Sopenharmony_ci    file_handle: HANDLE
4967db96d56Sopenharmony_ci    security_attributes: LPSECURITY_ATTRIBUTES
4977db96d56Sopenharmony_ci    protect: DWORD
4987db96d56Sopenharmony_ci    max_size_high: DWORD
4997db96d56Sopenharmony_ci    max_size_low: DWORD
5007db96d56Sopenharmony_ci    name: LPCWSTR
5017db96d56Sopenharmony_ci    /
5027db96d56Sopenharmony_ci[clinic start generated code]*/
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_cistatic HANDLE
5057db96d56Sopenharmony_ci_winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle,
5067db96d56Sopenharmony_ci                               LPSECURITY_ATTRIBUTES security_attributes,
5077db96d56Sopenharmony_ci                               DWORD protect, DWORD max_size_high,
5087db96d56Sopenharmony_ci                               DWORD max_size_low, LPCWSTR name)
5097db96d56Sopenharmony_ci/*[clinic end generated code: output=6c0a4d5cf7f6fcc6 input=3dc5cf762a74dee8]*/
5107db96d56Sopenharmony_ci{
5117db96d56Sopenharmony_ci    HANDLE handle;
5127db96d56Sopenharmony_ci
5137db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
5147db96d56Sopenharmony_ci    handle = CreateFileMappingW(file_handle, security_attributes,
5157db96d56Sopenharmony_ci                                protect, max_size_high, max_size_low,
5167db96d56Sopenharmony_ci                                name);
5177db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
5187db96d56Sopenharmony_ci
5197db96d56Sopenharmony_ci    if (handle == NULL) {
5207db96d56Sopenharmony_ci        PyObject *temp = PyUnicode_FromWideChar(name, -1);
5217db96d56Sopenharmony_ci        PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp);
5227db96d56Sopenharmony_ci        Py_XDECREF(temp);
5237db96d56Sopenharmony_ci        handle = INVALID_HANDLE_VALUE;
5247db96d56Sopenharmony_ci    }
5257db96d56Sopenharmony_ci
5267db96d56Sopenharmony_ci    return handle;
5277db96d56Sopenharmony_ci}
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_ci/*[clinic input]
5307db96d56Sopenharmony_ci_winapi.CreateJunction
5317db96d56Sopenharmony_ci
5327db96d56Sopenharmony_ci    src_path: LPCWSTR
5337db96d56Sopenharmony_ci    dst_path: LPCWSTR
5347db96d56Sopenharmony_ci    /
5357db96d56Sopenharmony_ci[clinic start generated code]*/
5367db96d56Sopenharmony_ci
5377db96d56Sopenharmony_cistatic PyObject *
5387db96d56Sopenharmony_ci_winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path,
5397db96d56Sopenharmony_ci                            LPCWSTR dst_path)
5407db96d56Sopenharmony_ci/*[clinic end generated code: output=44b3f5e9bbcc4271 input=963d29b44b9384a7]*/
5417db96d56Sopenharmony_ci{
5427db96d56Sopenharmony_ci    /* Privilege adjustment */
5437db96d56Sopenharmony_ci    HANDLE token = NULL;
5447db96d56Sopenharmony_ci    TOKEN_PRIVILEGES tp;
5457db96d56Sopenharmony_ci
5467db96d56Sopenharmony_ci    /* Reparse data buffer */
5477db96d56Sopenharmony_ci    const USHORT prefix_len = 4;
5487db96d56Sopenharmony_ci    USHORT print_len = 0;
5497db96d56Sopenharmony_ci    USHORT rdb_size = 0;
5507db96d56Sopenharmony_ci    _Py_PREPARSE_DATA_BUFFER rdb = NULL;
5517db96d56Sopenharmony_ci
5527db96d56Sopenharmony_ci    /* Junction point creation */
5537db96d56Sopenharmony_ci    HANDLE junction = NULL;
5547db96d56Sopenharmony_ci    DWORD ret = 0;
5557db96d56Sopenharmony_ci
5567db96d56Sopenharmony_ci    if (src_path == NULL || dst_path == NULL)
5577db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);
5587db96d56Sopenharmony_ci
5597db96d56Sopenharmony_ci    if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0)
5607db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);
5617db96d56Sopenharmony_ci
5627db96d56Sopenharmony_ci    if (PySys_Audit("_winapi.CreateJunction", "uu", src_path, dst_path) < 0) {
5637db96d56Sopenharmony_ci        return NULL;
5647db96d56Sopenharmony_ci    }
5657db96d56Sopenharmony_ci
5667db96d56Sopenharmony_ci    /* Adjust privileges to allow rewriting directory entry as a
5677db96d56Sopenharmony_ci       junction point. */
5687db96d56Sopenharmony_ci    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
5697db96d56Sopenharmony_ci        goto cleanup;
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ci    if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid))
5727db96d56Sopenharmony_ci        goto cleanup;
5737db96d56Sopenharmony_ci
5747db96d56Sopenharmony_ci    tp.PrivilegeCount = 1;
5757db96d56Sopenharmony_ci    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
5767db96d56Sopenharmony_ci    if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
5777db96d56Sopenharmony_ci                               NULL, NULL))
5787db96d56Sopenharmony_ci        goto cleanup;
5797db96d56Sopenharmony_ci
5807db96d56Sopenharmony_ci    if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES)
5817db96d56Sopenharmony_ci        goto cleanup;
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ci    /* Store the absolute link target path length in print_len. */
5847db96d56Sopenharmony_ci    print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL);
5857db96d56Sopenharmony_ci    if (print_len == 0)
5867db96d56Sopenharmony_ci        goto cleanup;
5877db96d56Sopenharmony_ci
5887db96d56Sopenharmony_ci    /* NUL terminator should not be part of print_len. */
5897db96d56Sopenharmony_ci    --print_len;
5907db96d56Sopenharmony_ci
5917db96d56Sopenharmony_ci    /* REPARSE_DATA_BUFFER usage is heavily under-documented, especially for
5927db96d56Sopenharmony_ci       junction points. Here's what I've learned along the way:
5937db96d56Sopenharmony_ci       - A junction point has two components: a print name and a substitute
5947db96d56Sopenharmony_ci         name. They both describe the link target, but the substitute name is
5957db96d56Sopenharmony_ci         the physical target and the print name is shown in directory listings.
5967db96d56Sopenharmony_ci       - The print name must be a native name, prefixed with "\??\".
5977db96d56Sopenharmony_ci       - Both names are stored after each other in the same buffer (the
5987db96d56Sopenharmony_ci         PathBuffer) and both must be NUL-terminated.
5997db96d56Sopenharmony_ci       - There are four members defining their respective offset and length
6007db96d56Sopenharmony_ci         inside PathBuffer: SubstituteNameOffset, SubstituteNameLength,
6017db96d56Sopenharmony_ci         PrintNameOffset and PrintNameLength.
6027db96d56Sopenharmony_ci       - The total size we need to allocate for the REPARSE_DATA_BUFFER, thus,
6037db96d56Sopenharmony_ci         is the sum of:
6047db96d56Sopenharmony_ci         - the fixed header size (REPARSE_DATA_BUFFER_HEADER_SIZE)
6057db96d56Sopenharmony_ci         - the size of the MountPointReparseBuffer member without the PathBuffer
6067db96d56Sopenharmony_ci         - the size of the prefix ("\??\") in bytes
6077db96d56Sopenharmony_ci         - the size of the print name in bytes
6087db96d56Sopenharmony_ci         - the size of the substitute name in bytes
6097db96d56Sopenharmony_ci         - the size of two NUL terminators in bytes */
6107db96d56Sopenharmony_ci    rdb_size = _Py_REPARSE_DATA_BUFFER_HEADER_SIZE +
6117db96d56Sopenharmony_ci        sizeof(rdb->MountPointReparseBuffer) -
6127db96d56Sopenharmony_ci        sizeof(rdb->MountPointReparseBuffer.PathBuffer) +
6137db96d56Sopenharmony_ci        /* Two +1's for NUL terminators. */
6147db96d56Sopenharmony_ci        (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR);
6157db96d56Sopenharmony_ci    rdb = (_Py_PREPARSE_DATA_BUFFER)PyMem_RawCalloc(1, rdb_size);
6167db96d56Sopenharmony_ci    if (rdb == NULL)
6177db96d56Sopenharmony_ci        goto cleanup;
6187db96d56Sopenharmony_ci
6197db96d56Sopenharmony_ci    rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
6207db96d56Sopenharmony_ci    rdb->ReparseDataLength = rdb_size - _Py_REPARSE_DATA_BUFFER_HEADER_SIZE;
6217db96d56Sopenharmony_ci    rdb->MountPointReparseBuffer.SubstituteNameOffset = 0;
6227db96d56Sopenharmony_ci    rdb->MountPointReparseBuffer.SubstituteNameLength =
6237db96d56Sopenharmony_ci        (prefix_len + print_len) * sizeof(WCHAR);
6247db96d56Sopenharmony_ci    rdb->MountPointReparseBuffer.PrintNameOffset =
6257db96d56Sopenharmony_ci        rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
6267db96d56Sopenharmony_ci    rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR);
6277db96d56Sopenharmony_ci
6287db96d56Sopenharmony_ci    /* Store the full native path of link target at the substitute name
6297db96d56Sopenharmony_ci       offset (0). */
6307db96d56Sopenharmony_ci    wcscpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\");
6317db96d56Sopenharmony_ci    if (GetFullPathNameW(src_path, print_len + 1,
6327db96d56Sopenharmony_ci                         rdb->MountPointReparseBuffer.PathBuffer + prefix_len,
6337db96d56Sopenharmony_ci                         NULL) == 0)
6347db96d56Sopenharmony_ci        goto cleanup;
6357db96d56Sopenharmony_ci
6367db96d56Sopenharmony_ci    /* Copy everything but the native prefix to the print name offset. */
6377db96d56Sopenharmony_ci    wcscpy(rdb->MountPointReparseBuffer.PathBuffer +
6387db96d56Sopenharmony_ci             prefix_len + print_len + 1,
6397db96d56Sopenharmony_ci             rdb->MountPointReparseBuffer.PathBuffer + prefix_len);
6407db96d56Sopenharmony_ci
6417db96d56Sopenharmony_ci    /* Create a directory for the junction point. */
6427db96d56Sopenharmony_ci    if (!CreateDirectoryW(dst_path, NULL))
6437db96d56Sopenharmony_ci        goto cleanup;
6447db96d56Sopenharmony_ci
6457db96d56Sopenharmony_ci    junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
6467db96d56Sopenharmony_ci        OPEN_EXISTING,
6477db96d56Sopenharmony_ci        FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
6487db96d56Sopenharmony_ci    if (junction == INVALID_HANDLE_VALUE)
6497db96d56Sopenharmony_ci        goto cleanup;
6507db96d56Sopenharmony_ci
6517db96d56Sopenharmony_ci    /* Make the directory entry a junction point. */
6527db96d56Sopenharmony_ci    if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size,
6537db96d56Sopenharmony_ci                         NULL, 0, &ret, NULL))
6547db96d56Sopenharmony_ci        goto cleanup;
6557db96d56Sopenharmony_ci
6567db96d56Sopenharmony_cicleanup:
6577db96d56Sopenharmony_ci    ret = GetLastError();
6587db96d56Sopenharmony_ci
6597db96d56Sopenharmony_ci    CloseHandle(token);
6607db96d56Sopenharmony_ci    CloseHandle(junction);
6617db96d56Sopenharmony_ci    PyMem_RawFree(rdb);
6627db96d56Sopenharmony_ci
6637db96d56Sopenharmony_ci    if (ret != 0)
6647db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(ret);
6657db96d56Sopenharmony_ci
6667db96d56Sopenharmony_ci    Py_RETURN_NONE;
6677db96d56Sopenharmony_ci}
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ci/*[clinic input]
6707db96d56Sopenharmony_ci_winapi.CreateNamedPipe -> HANDLE
6717db96d56Sopenharmony_ci
6727db96d56Sopenharmony_ci    name: LPCTSTR
6737db96d56Sopenharmony_ci    open_mode: DWORD
6747db96d56Sopenharmony_ci    pipe_mode: DWORD
6757db96d56Sopenharmony_ci    max_instances: DWORD
6767db96d56Sopenharmony_ci    out_buffer_size: DWORD
6777db96d56Sopenharmony_ci    in_buffer_size: DWORD
6787db96d56Sopenharmony_ci    default_timeout: DWORD
6797db96d56Sopenharmony_ci    security_attributes: LPSECURITY_ATTRIBUTES
6807db96d56Sopenharmony_ci    /
6817db96d56Sopenharmony_ci[clinic start generated code]*/
6827db96d56Sopenharmony_ci
6837db96d56Sopenharmony_cistatic HANDLE
6847db96d56Sopenharmony_ci_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode,
6857db96d56Sopenharmony_ci                             DWORD pipe_mode, DWORD max_instances,
6867db96d56Sopenharmony_ci                             DWORD out_buffer_size, DWORD in_buffer_size,
6877db96d56Sopenharmony_ci                             DWORD default_timeout,
6887db96d56Sopenharmony_ci                             LPSECURITY_ATTRIBUTES security_attributes)
6897db96d56Sopenharmony_ci/*[clinic end generated code: output=80f8c07346a94fbc input=5a73530b84d8bc37]*/
6907db96d56Sopenharmony_ci{
6917db96d56Sopenharmony_ci    HANDLE handle;
6927db96d56Sopenharmony_ci
6937db96d56Sopenharmony_ci    if (PySys_Audit("_winapi.CreateNamedPipe", "uII",
6947db96d56Sopenharmony_ci                    name, open_mode, pipe_mode) < 0) {
6957db96d56Sopenharmony_ci        return INVALID_HANDLE_VALUE;
6967db96d56Sopenharmony_ci    }
6977db96d56Sopenharmony_ci
6987db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
6997db96d56Sopenharmony_ci    handle = CreateNamedPipe(name, open_mode, pipe_mode,
7007db96d56Sopenharmony_ci                             max_instances, out_buffer_size,
7017db96d56Sopenharmony_ci                             in_buffer_size, default_timeout,
7027db96d56Sopenharmony_ci                             security_attributes);
7037db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
7047db96d56Sopenharmony_ci
7057db96d56Sopenharmony_ci    if (handle == INVALID_HANDLE_VALUE)
7067db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(0);
7077db96d56Sopenharmony_ci
7087db96d56Sopenharmony_ci    return handle;
7097db96d56Sopenharmony_ci}
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci/*[clinic input]
7127db96d56Sopenharmony_ci_winapi.CreatePipe
7137db96d56Sopenharmony_ci
7147db96d56Sopenharmony_ci    pipe_attrs: object
7157db96d56Sopenharmony_ci        Ignored internally, can be None.
7167db96d56Sopenharmony_ci    size: DWORD
7177db96d56Sopenharmony_ci    /
7187db96d56Sopenharmony_ci
7197db96d56Sopenharmony_ciCreate an anonymous pipe.
7207db96d56Sopenharmony_ci
7217db96d56Sopenharmony_ciReturns a 2-tuple of handles, to the read and write ends of the pipe.
7227db96d56Sopenharmony_ci[clinic start generated code]*/
7237db96d56Sopenharmony_ci
7247db96d56Sopenharmony_cistatic PyObject *
7257db96d56Sopenharmony_ci_winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size)
7267db96d56Sopenharmony_ci/*[clinic end generated code: output=1c4411d8699f0925 input=c4f2cfa56ef68d90]*/
7277db96d56Sopenharmony_ci{
7287db96d56Sopenharmony_ci    HANDLE read_pipe;
7297db96d56Sopenharmony_ci    HANDLE write_pipe;
7307db96d56Sopenharmony_ci    BOOL result;
7317db96d56Sopenharmony_ci
7327db96d56Sopenharmony_ci    if (PySys_Audit("_winapi.CreatePipe", NULL) < 0) {
7337db96d56Sopenharmony_ci        return NULL;
7347db96d56Sopenharmony_ci    }
7357db96d56Sopenharmony_ci
7367db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
7377db96d56Sopenharmony_ci    result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
7387db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
7397db96d56Sopenharmony_ci
7407db96d56Sopenharmony_ci    if (! result)
7417db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(GetLastError());
7427db96d56Sopenharmony_ci
7437db96d56Sopenharmony_ci    return Py_BuildValue(
7447db96d56Sopenharmony_ci        "NN", HANDLE_TO_PYNUM(read_pipe), HANDLE_TO_PYNUM(write_pipe));
7457db96d56Sopenharmony_ci}
7467db96d56Sopenharmony_ci
7477db96d56Sopenharmony_ci/* helpers for createprocess */
7487db96d56Sopenharmony_ci
7497db96d56Sopenharmony_cistatic unsigned long
7507db96d56Sopenharmony_cigetulong(PyObject* obj, const char* name)
7517db96d56Sopenharmony_ci{
7527db96d56Sopenharmony_ci    PyObject* value;
7537db96d56Sopenharmony_ci    unsigned long ret;
7547db96d56Sopenharmony_ci
7557db96d56Sopenharmony_ci    value = PyObject_GetAttrString(obj, name);
7567db96d56Sopenharmony_ci    if (! value) {
7577db96d56Sopenharmony_ci        PyErr_Clear(); /* FIXME: propagate error? */
7587db96d56Sopenharmony_ci        return 0;
7597db96d56Sopenharmony_ci    }
7607db96d56Sopenharmony_ci    ret = PyLong_AsUnsignedLong(value);
7617db96d56Sopenharmony_ci    Py_DECREF(value);
7627db96d56Sopenharmony_ci    return ret;
7637db96d56Sopenharmony_ci}
7647db96d56Sopenharmony_ci
7657db96d56Sopenharmony_cistatic HANDLE
7667db96d56Sopenharmony_cigethandle(PyObject* obj, const char* name)
7677db96d56Sopenharmony_ci{
7687db96d56Sopenharmony_ci    PyObject* value;
7697db96d56Sopenharmony_ci    HANDLE ret;
7707db96d56Sopenharmony_ci
7717db96d56Sopenharmony_ci    value = PyObject_GetAttrString(obj, name);
7727db96d56Sopenharmony_ci    if (! value) {
7737db96d56Sopenharmony_ci        PyErr_Clear(); /* FIXME: propagate error? */
7747db96d56Sopenharmony_ci        return NULL;
7757db96d56Sopenharmony_ci    }
7767db96d56Sopenharmony_ci    if (value == Py_None)
7777db96d56Sopenharmony_ci        ret = NULL;
7787db96d56Sopenharmony_ci    else
7797db96d56Sopenharmony_ci        ret = PYNUM_TO_HANDLE(value);
7807db96d56Sopenharmony_ci    Py_DECREF(value);
7817db96d56Sopenharmony_ci    return ret;
7827db96d56Sopenharmony_ci}
7837db96d56Sopenharmony_ci
7847db96d56Sopenharmony_cistatic wchar_t *
7857db96d56Sopenharmony_cigetenvironment(PyObject* environment)
7867db96d56Sopenharmony_ci{
7877db96d56Sopenharmony_ci    Py_ssize_t i, envsize, totalsize;
7887db96d56Sopenharmony_ci    wchar_t *buffer = NULL, *p, *end;
7897db96d56Sopenharmony_ci    PyObject *keys, *values;
7907db96d56Sopenharmony_ci
7917db96d56Sopenharmony_ci    /* convert environment dictionary to windows environment string */
7927db96d56Sopenharmony_ci    if (! PyMapping_Check(environment)) {
7937db96d56Sopenharmony_ci        PyErr_SetString(
7947db96d56Sopenharmony_ci            PyExc_TypeError, "environment must be dictionary or None");
7957db96d56Sopenharmony_ci        return NULL;
7967db96d56Sopenharmony_ci    }
7977db96d56Sopenharmony_ci
7987db96d56Sopenharmony_ci    keys = PyMapping_Keys(environment);
7997db96d56Sopenharmony_ci    if (!keys) {
8007db96d56Sopenharmony_ci        return NULL;
8017db96d56Sopenharmony_ci    }
8027db96d56Sopenharmony_ci    values = PyMapping_Values(environment);
8037db96d56Sopenharmony_ci    if (!values) {
8047db96d56Sopenharmony_ci        goto error;
8057db96d56Sopenharmony_ci    }
8067db96d56Sopenharmony_ci
8077db96d56Sopenharmony_ci    envsize = PyList_GET_SIZE(keys);
8087db96d56Sopenharmony_ci    if (PyList_GET_SIZE(values) != envsize) {
8097db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError,
8107db96d56Sopenharmony_ci            "environment changed size during iteration");
8117db96d56Sopenharmony_ci        goto error;
8127db96d56Sopenharmony_ci    }
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci    totalsize = 1; /* trailing null character */
8157db96d56Sopenharmony_ci    for (i = 0; i < envsize; i++) {
8167db96d56Sopenharmony_ci        PyObject* key = PyList_GET_ITEM(keys, i);
8177db96d56Sopenharmony_ci        PyObject* value = PyList_GET_ITEM(values, i);
8187db96d56Sopenharmony_ci        Py_ssize_t size;
8197db96d56Sopenharmony_ci
8207db96d56Sopenharmony_ci        if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) {
8217db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
8227db96d56Sopenharmony_ci                "environment can only contain strings");
8237db96d56Sopenharmony_ci            goto error;
8247db96d56Sopenharmony_ci        }
8257db96d56Sopenharmony_ci        if (PyUnicode_FindChar(key, '\0', 0, PyUnicode_GET_LENGTH(key), 1) != -1 ||
8267db96d56Sopenharmony_ci            PyUnicode_FindChar(value, '\0', 0, PyUnicode_GET_LENGTH(value), 1) != -1)
8277db96d56Sopenharmony_ci        {
8287db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError, "embedded null character");
8297db96d56Sopenharmony_ci            goto error;
8307db96d56Sopenharmony_ci        }
8317db96d56Sopenharmony_ci        /* Search from index 1 because on Windows starting '=' is allowed for
8327db96d56Sopenharmony_ci           defining hidden environment variables. */
8337db96d56Sopenharmony_ci        if (PyUnicode_GET_LENGTH(key) == 0 ||
8347db96d56Sopenharmony_ci            PyUnicode_FindChar(key, '=', 1, PyUnicode_GET_LENGTH(key), 1) != -1)
8357db96d56Sopenharmony_ci        {
8367db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
8377db96d56Sopenharmony_ci            goto error;
8387db96d56Sopenharmony_ci        }
8397db96d56Sopenharmony_ci
8407db96d56Sopenharmony_ci        size = PyUnicode_AsWideChar(key, NULL, 0);
8417db96d56Sopenharmony_ci        assert(size > 1);
8427db96d56Sopenharmony_ci        if (totalsize > PY_SSIZE_T_MAX - size) {
8437db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OverflowError, "environment too long");
8447db96d56Sopenharmony_ci            goto error;
8457db96d56Sopenharmony_ci        }
8467db96d56Sopenharmony_ci        totalsize += size;    /* including '=' */
8477db96d56Sopenharmony_ci
8487db96d56Sopenharmony_ci        size = PyUnicode_AsWideChar(value, NULL, 0);
8497db96d56Sopenharmony_ci        assert(size > 0);
8507db96d56Sopenharmony_ci        if (totalsize > PY_SSIZE_T_MAX - size) {
8517db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OverflowError, "environment too long");
8527db96d56Sopenharmony_ci            goto error;
8537db96d56Sopenharmony_ci        }
8547db96d56Sopenharmony_ci        totalsize += size;  /* including trailing '\0' */
8557db96d56Sopenharmony_ci    }
8567db96d56Sopenharmony_ci
8577db96d56Sopenharmony_ci    buffer = PyMem_NEW(wchar_t, totalsize);
8587db96d56Sopenharmony_ci    if (! buffer) {
8597db96d56Sopenharmony_ci        PyErr_NoMemory();
8607db96d56Sopenharmony_ci        goto error;
8617db96d56Sopenharmony_ci    }
8627db96d56Sopenharmony_ci    p = buffer;
8637db96d56Sopenharmony_ci    end = buffer + totalsize;
8647db96d56Sopenharmony_ci
8657db96d56Sopenharmony_ci    for (i = 0; i < envsize; i++) {
8667db96d56Sopenharmony_ci        PyObject* key = PyList_GET_ITEM(keys, i);
8677db96d56Sopenharmony_ci        PyObject* value = PyList_GET_ITEM(values, i);
8687db96d56Sopenharmony_ci        Py_ssize_t size = PyUnicode_AsWideChar(key, p, end - p);
8697db96d56Sopenharmony_ci        assert(1 <= size && size < end - p);
8707db96d56Sopenharmony_ci        p += size;
8717db96d56Sopenharmony_ci        *p++ = L'=';
8727db96d56Sopenharmony_ci        size = PyUnicode_AsWideChar(value, p, end - p);
8737db96d56Sopenharmony_ci        assert(0 <= size && size < end - p);
8747db96d56Sopenharmony_ci        p += size + 1;
8757db96d56Sopenharmony_ci    }
8767db96d56Sopenharmony_ci
8777db96d56Sopenharmony_ci    /* add trailing null character */
8787db96d56Sopenharmony_ci    *p++ = L'\0';
8797db96d56Sopenharmony_ci    assert(p == end);
8807db96d56Sopenharmony_ci
8817db96d56Sopenharmony_ci error:
8827db96d56Sopenharmony_ci    Py_XDECREF(keys);
8837db96d56Sopenharmony_ci    Py_XDECREF(values);
8847db96d56Sopenharmony_ci    return buffer;
8857db96d56Sopenharmony_ci}
8867db96d56Sopenharmony_ci
8877db96d56Sopenharmony_cistatic LPHANDLE
8887db96d56Sopenharmony_cigethandlelist(PyObject *mapping, const char *name, Py_ssize_t *size)
8897db96d56Sopenharmony_ci{
8907db96d56Sopenharmony_ci    LPHANDLE ret = NULL;
8917db96d56Sopenharmony_ci    PyObject *value_fast = NULL;
8927db96d56Sopenharmony_ci    PyObject *value;
8937db96d56Sopenharmony_ci    Py_ssize_t i;
8947db96d56Sopenharmony_ci
8957db96d56Sopenharmony_ci    value = PyMapping_GetItemString(mapping, name);
8967db96d56Sopenharmony_ci    if (!value) {
8977db96d56Sopenharmony_ci        PyErr_Clear();
8987db96d56Sopenharmony_ci        return NULL;
8997db96d56Sopenharmony_ci    }
9007db96d56Sopenharmony_ci
9017db96d56Sopenharmony_ci    if (value == Py_None) {
9027db96d56Sopenharmony_ci        goto cleanup;
9037db96d56Sopenharmony_ci    }
9047db96d56Sopenharmony_ci
9057db96d56Sopenharmony_ci    value_fast = PySequence_Fast(value, "handle_list must be a sequence or None");
9067db96d56Sopenharmony_ci    if (value_fast == NULL)
9077db96d56Sopenharmony_ci        goto cleanup;
9087db96d56Sopenharmony_ci
9097db96d56Sopenharmony_ci    *size = PySequence_Fast_GET_SIZE(value_fast) * sizeof(HANDLE);
9107db96d56Sopenharmony_ci
9117db96d56Sopenharmony_ci    /* Passing an empty array causes CreateProcess to fail so just don't set it */
9127db96d56Sopenharmony_ci    if (*size == 0) {
9137db96d56Sopenharmony_ci        goto cleanup;
9147db96d56Sopenharmony_ci    }
9157db96d56Sopenharmony_ci
9167db96d56Sopenharmony_ci    ret = PyMem_Malloc(*size);
9177db96d56Sopenharmony_ci    if (ret == NULL)
9187db96d56Sopenharmony_ci        goto cleanup;
9197db96d56Sopenharmony_ci
9207db96d56Sopenharmony_ci    for (i = 0; i < PySequence_Fast_GET_SIZE(value_fast); i++) {
9217db96d56Sopenharmony_ci        ret[i] = PYNUM_TO_HANDLE(PySequence_Fast_GET_ITEM(value_fast, i));
9227db96d56Sopenharmony_ci        if (ret[i] == (HANDLE)-1 && PyErr_Occurred()) {
9237db96d56Sopenharmony_ci            PyMem_Free(ret);
9247db96d56Sopenharmony_ci            ret = NULL;
9257db96d56Sopenharmony_ci            goto cleanup;
9267db96d56Sopenharmony_ci        }
9277db96d56Sopenharmony_ci    }
9287db96d56Sopenharmony_ci
9297db96d56Sopenharmony_cicleanup:
9307db96d56Sopenharmony_ci    Py_DECREF(value);
9317db96d56Sopenharmony_ci    Py_XDECREF(value_fast);
9327db96d56Sopenharmony_ci    return ret;
9337db96d56Sopenharmony_ci}
9347db96d56Sopenharmony_ci
9357db96d56Sopenharmony_citypedef struct {
9367db96d56Sopenharmony_ci    LPPROC_THREAD_ATTRIBUTE_LIST attribute_list;
9377db96d56Sopenharmony_ci    LPHANDLE handle_list;
9387db96d56Sopenharmony_ci} AttributeList;
9397db96d56Sopenharmony_ci
9407db96d56Sopenharmony_cistatic void
9417db96d56Sopenharmony_cifreeattributelist(AttributeList *attribute_list)
9427db96d56Sopenharmony_ci{
9437db96d56Sopenharmony_ci    if (attribute_list->attribute_list != NULL) {
9447db96d56Sopenharmony_ci        DeleteProcThreadAttributeList(attribute_list->attribute_list);
9457db96d56Sopenharmony_ci        PyMem_Free(attribute_list->attribute_list);
9467db96d56Sopenharmony_ci    }
9477db96d56Sopenharmony_ci
9487db96d56Sopenharmony_ci    PyMem_Free(attribute_list->handle_list);
9497db96d56Sopenharmony_ci
9507db96d56Sopenharmony_ci    memset(attribute_list, 0, sizeof(*attribute_list));
9517db96d56Sopenharmony_ci}
9527db96d56Sopenharmony_ci
9537db96d56Sopenharmony_cistatic int
9547db96d56Sopenharmony_cigetattributelist(PyObject *obj, const char *name, AttributeList *attribute_list)
9557db96d56Sopenharmony_ci{
9567db96d56Sopenharmony_ci    int ret = 0;
9577db96d56Sopenharmony_ci    DWORD err;
9587db96d56Sopenharmony_ci    BOOL result;
9597db96d56Sopenharmony_ci    PyObject *value;
9607db96d56Sopenharmony_ci    Py_ssize_t handle_list_size;
9617db96d56Sopenharmony_ci    DWORD attribute_count = 0;
9627db96d56Sopenharmony_ci    SIZE_T attribute_list_size = 0;
9637db96d56Sopenharmony_ci
9647db96d56Sopenharmony_ci    value = PyObject_GetAttrString(obj, name);
9657db96d56Sopenharmony_ci    if (!value) {
9667db96d56Sopenharmony_ci        PyErr_Clear(); /* FIXME: propagate error? */
9677db96d56Sopenharmony_ci        return 0;
9687db96d56Sopenharmony_ci    }
9697db96d56Sopenharmony_ci
9707db96d56Sopenharmony_ci    if (value == Py_None) {
9717db96d56Sopenharmony_ci        ret = 0;
9727db96d56Sopenharmony_ci        goto cleanup;
9737db96d56Sopenharmony_ci    }
9747db96d56Sopenharmony_ci
9757db96d56Sopenharmony_ci    if (!PyMapping_Check(value)) {
9767db96d56Sopenharmony_ci        ret = -1;
9777db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError, "%s must be a mapping or None", name);
9787db96d56Sopenharmony_ci        goto cleanup;
9797db96d56Sopenharmony_ci    }
9807db96d56Sopenharmony_ci
9817db96d56Sopenharmony_ci    attribute_list->handle_list = gethandlelist(value, "handle_list", &handle_list_size);
9827db96d56Sopenharmony_ci    if (attribute_list->handle_list == NULL && PyErr_Occurred()) {
9837db96d56Sopenharmony_ci        ret = -1;
9847db96d56Sopenharmony_ci        goto cleanup;
9857db96d56Sopenharmony_ci    }
9867db96d56Sopenharmony_ci
9877db96d56Sopenharmony_ci    if (attribute_list->handle_list != NULL)
9887db96d56Sopenharmony_ci        ++attribute_count;
9897db96d56Sopenharmony_ci
9907db96d56Sopenharmony_ci    /* Get how many bytes we need for the attribute list */
9917db96d56Sopenharmony_ci    result = InitializeProcThreadAttributeList(NULL, attribute_count, 0, &attribute_list_size);
9927db96d56Sopenharmony_ci    if (result || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
9937db96d56Sopenharmony_ci        ret = -1;
9947db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(GetLastError());
9957db96d56Sopenharmony_ci        goto cleanup;
9967db96d56Sopenharmony_ci    }
9977db96d56Sopenharmony_ci
9987db96d56Sopenharmony_ci    attribute_list->attribute_list = PyMem_Malloc(attribute_list_size);
9997db96d56Sopenharmony_ci    if (attribute_list->attribute_list == NULL) {
10007db96d56Sopenharmony_ci        ret = -1;
10017db96d56Sopenharmony_ci        goto cleanup;
10027db96d56Sopenharmony_ci    }
10037db96d56Sopenharmony_ci
10047db96d56Sopenharmony_ci    result = InitializeProcThreadAttributeList(
10057db96d56Sopenharmony_ci        attribute_list->attribute_list,
10067db96d56Sopenharmony_ci        attribute_count,
10077db96d56Sopenharmony_ci        0,
10087db96d56Sopenharmony_ci        &attribute_list_size);
10097db96d56Sopenharmony_ci    if (!result) {
10107db96d56Sopenharmony_ci        err = GetLastError();
10117db96d56Sopenharmony_ci
10127db96d56Sopenharmony_ci        /* So that we won't call DeleteProcThreadAttributeList */
10137db96d56Sopenharmony_ci        PyMem_Free(attribute_list->attribute_list);
10147db96d56Sopenharmony_ci        attribute_list->attribute_list = NULL;
10157db96d56Sopenharmony_ci
10167db96d56Sopenharmony_ci        ret = -1;
10177db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(err);
10187db96d56Sopenharmony_ci        goto cleanup;
10197db96d56Sopenharmony_ci    }
10207db96d56Sopenharmony_ci
10217db96d56Sopenharmony_ci    if (attribute_list->handle_list != NULL) {
10227db96d56Sopenharmony_ci        result = UpdateProcThreadAttribute(
10237db96d56Sopenharmony_ci            attribute_list->attribute_list,
10247db96d56Sopenharmony_ci            0,
10257db96d56Sopenharmony_ci            PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
10267db96d56Sopenharmony_ci            attribute_list->handle_list,
10277db96d56Sopenharmony_ci            handle_list_size,
10287db96d56Sopenharmony_ci            NULL,
10297db96d56Sopenharmony_ci            NULL);
10307db96d56Sopenharmony_ci        if (!result) {
10317db96d56Sopenharmony_ci            ret = -1;
10327db96d56Sopenharmony_ci            PyErr_SetFromWindowsErr(GetLastError());
10337db96d56Sopenharmony_ci            goto cleanup;
10347db96d56Sopenharmony_ci        }
10357db96d56Sopenharmony_ci    }
10367db96d56Sopenharmony_ci
10377db96d56Sopenharmony_cicleanup:
10387db96d56Sopenharmony_ci    Py_DECREF(value);
10397db96d56Sopenharmony_ci
10407db96d56Sopenharmony_ci    if (ret < 0)
10417db96d56Sopenharmony_ci        freeattributelist(attribute_list);
10427db96d56Sopenharmony_ci
10437db96d56Sopenharmony_ci    return ret;
10447db96d56Sopenharmony_ci}
10457db96d56Sopenharmony_ci
10467db96d56Sopenharmony_ci/*[clinic input]
10477db96d56Sopenharmony_ci_winapi.CreateProcess
10487db96d56Sopenharmony_ci
10497db96d56Sopenharmony_ci    application_name: Py_UNICODE(accept={str, NoneType})
10507db96d56Sopenharmony_ci    command_line: object
10517db96d56Sopenharmony_ci        Can be str or None
10527db96d56Sopenharmony_ci    proc_attrs: object
10537db96d56Sopenharmony_ci        Ignored internally, can be None.
10547db96d56Sopenharmony_ci    thread_attrs: object
10557db96d56Sopenharmony_ci        Ignored internally, can be None.
10567db96d56Sopenharmony_ci    inherit_handles: BOOL
10577db96d56Sopenharmony_ci    creation_flags: DWORD
10587db96d56Sopenharmony_ci    env_mapping: object
10597db96d56Sopenharmony_ci    current_directory: Py_UNICODE(accept={str, NoneType})
10607db96d56Sopenharmony_ci    startup_info: object
10617db96d56Sopenharmony_ci    /
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_ciCreate a new process and its primary thread.
10647db96d56Sopenharmony_ci
10657db96d56Sopenharmony_ciThe return value is a tuple of the process handle, thread handle,
10667db96d56Sopenharmony_ciprocess ID, and thread ID.
10677db96d56Sopenharmony_ci[clinic start generated code]*/
10687db96d56Sopenharmony_ci
10697db96d56Sopenharmony_cistatic PyObject *
10707db96d56Sopenharmony_ci_winapi_CreateProcess_impl(PyObject *module,
10717db96d56Sopenharmony_ci                           const Py_UNICODE *application_name,
10727db96d56Sopenharmony_ci                           PyObject *command_line, PyObject *proc_attrs,
10737db96d56Sopenharmony_ci                           PyObject *thread_attrs, BOOL inherit_handles,
10747db96d56Sopenharmony_ci                           DWORD creation_flags, PyObject *env_mapping,
10757db96d56Sopenharmony_ci                           const Py_UNICODE *current_directory,
10767db96d56Sopenharmony_ci                           PyObject *startup_info)
10777db96d56Sopenharmony_ci/*[clinic end generated code: output=9b2423a609230132 input=42ac293eaea03fc4]*/
10787db96d56Sopenharmony_ci{
10797db96d56Sopenharmony_ci    PyObject *ret = NULL;
10807db96d56Sopenharmony_ci    BOOL result;
10817db96d56Sopenharmony_ci    PROCESS_INFORMATION pi;
10827db96d56Sopenharmony_ci    STARTUPINFOEXW si;
10837db96d56Sopenharmony_ci    wchar_t *wenvironment = NULL;
10847db96d56Sopenharmony_ci    wchar_t *command_line_copy = NULL;
10857db96d56Sopenharmony_ci    AttributeList attribute_list = {0};
10867db96d56Sopenharmony_ci
10877db96d56Sopenharmony_ci    if (PySys_Audit("_winapi.CreateProcess", "uuu", application_name,
10887db96d56Sopenharmony_ci                    command_line, current_directory) < 0) {
10897db96d56Sopenharmony_ci        return NULL;
10907db96d56Sopenharmony_ci    }
10917db96d56Sopenharmony_ci
10927db96d56Sopenharmony_ci    PyInterpreterState *interp = PyInterpreterState_Get();
10937db96d56Sopenharmony_ci    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
10947db96d56Sopenharmony_ci    if (config->_isolated_interpreter) {
10957db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError,
10967db96d56Sopenharmony_ci                        "subprocess not supported for isolated subinterpreters");
10977db96d56Sopenharmony_ci        return NULL;
10987db96d56Sopenharmony_ci    }
10997db96d56Sopenharmony_ci
11007db96d56Sopenharmony_ci    ZeroMemory(&si, sizeof(si));
11017db96d56Sopenharmony_ci    si.StartupInfo.cb = sizeof(si);
11027db96d56Sopenharmony_ci
11037db96d56Sopenharmony_ci    /* note: we only support a small subset of all SI attributes */
11047db96d56Sopenharmony_ci    si.StartupInfo.dwFlags = getulong(startup_info, "dwFlags");
11057db96d56Sopenharmony_ci    si.StartupInfo.wShowWindow = (WORD)getulong(startup_info, "wShowWindow");
11067db96d56Sopenharmony_ci    si.StartupInfo.hStdInput = gethandle(startup_info, "hStdInput");
11077db96d56Sopenharmony_ci    si.StartupInfo.hStdOutput = gethandle(startup_info, "hStdOutput");
11087db96d56Sopenharmony_ci    si.StartupInfo.hStdError = gethandle(startup_info, "hStdError");
11097db96d56Sopenharmony_ci    if (PyErr_Occurred())
11107db96d56Sopenharmony_ci        goto cleanup;
11117db96d56Sopenharmony_ci
11127db96d56Sopenharmony_ci    if (env_mapping != Py_None) {
11137db96d56Sopenharmony_ci        wenvironment = getenvironment(env_mapping);
11147db96d56Sopenharmony_ci        if (wenvironment == NULL) {
11157db96d56Sopenharmony_ci            goto cleanup;
11167db96d56Sopenharmony_ci        }
11177db96d56Sopenharmony_ci    }
11187db96d56Sopenharmony_ci
11197db96d56Sopenharmony_ci    if (getattributelist(startup_info, "lpAttributeList", &attribute_list) < 0)
11207db96d56Sopenharmony_ci        goto cleanup;
11217db96d56Sopenharmony_ci
11227db96d56Sopenharmony_ci    si.lpAttributeList = attribute_list.attribute_list;
11237db96d56Sopenharmony_ci    if (PyUnicode_Check(command_line)) {
11247db96d56Sopenharmony_ci        command_line_copy = PyUnicode_AsWideCharString(command_line, NULL);
11257db96d56Sopenharmony_ci        if (command_line_copy == NULL) {
11267db96d56Sopenharmony_ci            goto cleanup;
11277db96d56Sopenharmony_ci        }
11287db96d56Sopenharmony_ci    }
11297db96d56Sopenharmony_ci    else if (command_line != Py_None) {
11307db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
11317db96d56Sopenharmony_ci                     "CreateProcess() argument 2 must be str or None, not %s",
11327db96d56Sopenharmony_ci                     Py_TYPE(command_line)->tp_name);
11337db96d56Sopenharmony_ci        goto cleanup;
11347db96d56Sopenharmony_ci    }
11357db96d56Sopenharmony_ci
11367db96d56Sopenharmony_ci
11377db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
11387db96d56Sopenharmony_ci    result = CreateProcessW(application_name,
11397db96d56Sopenharmony_ci                           command_line_copy,
11407db96d56Sopenharmony_ci                           NULL,
11417db96d56Sopenharmony_ci                           NULL,
11427db96d56Sopenharmony_ci                           inherit_handles,
11437db96d56Sopenharmony_ci                           creation_flags | EXTENDED_STARTUPINFO_PRESENT |
11447db96d56Sopenharmony_ci                           CREATE_UNICODE_ENVIRONMENT,
11457db96d56Sopenharmony_ci                           wenvironment,
11467db96d56Sopenharmony_ci                           current_directory,
11477db96d56Sopenharmony_ci                           (LPSTARTUPINFOW)&si,
11487db96d56Sopenharmony_ci                           &pi);
11497db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
11507db96d56Sopenharmony_ci
11517db96d56Sopenharmony_ci    if (!result) {
11527db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(GetLastError());
11537db96d56Sopenharmony_ci        goto cleanup;
11547db96d56Sopenharmony_ci    }
11557db96d56Sopenharmony_ci
11567db96d56Sopenharmony_ci    ret = Py_BuildValue("NNkk",
11577db96d56Sopenharmony_ci                        HANDLE_TO_PYNUM(pi.hProcess),
11587db96d56Sopenharmony_ci                        HANDLE_TO_PYNUM(pi.hThread),
11597db96d56Sopenharmony_ci                        pi.dwProcessId,
11607db96d56Sopenharmony_ci                        pi.dwThreadId);
11617db96d56Sopenharmony_ci
11627db96d56Sopenharmony_cicleanup:
11637db96d56Sopenharmony_ci    PyMem_Free(command_line_copy);
11647db96d56Sopenharmony_ci    PyMem_Free(wenvironment);
11657db96d56Sopenharmony_ci    freeattributelist(&attribute_list);
11667db96d56Sopenharmony_ci
11677db96d56Sopenharmony_ci    return ret;
11687db96d56Sopenharmony_ci}
11697db96d56Sopenharmony_ci
11707db96d56Sopenharmony_ci/*[clinic input]
11717db96d56Sopenharmony_ci_winapi.DuplicateHandle -> HANDLE
11727db96d56Sopenharmony_ci
11737db96d56Sopenharmony_ci    source_process_handle: HANDLE
11747db96d56Sopenharmony_ci    source_handle: HANDLE
11757db96d56Sopenharmony_ci    target_process_handle: HANDLE
11767db96d56Sopenharmony_ci    desired_access: DWORD
11777db96d56Sopenharmony_ci    inherit_handle: BOOL
11787db96d56Sopenharmony_ci    options: DWORD = 0
11797db96d56Sopenharmony_ci    /
11807db96d56Sopenharmony_ci
11817db96d56Sopenharmony_ciReturn a duplicate handle object.
11827db96d56Sopenharmony_ci
11837db96d56Sopenharmony_ciThe duplicate handle refers to the same object as the original
11847db96d56Sopenharmony_cihandle. Therefore, any changes to the object are reflected
11857db96d56Sopenharmony_cithrough both handles.
11867db96d56Sopenharmony_ci[clinic start generated code]*/
11877db96d56Sopenharmony_ci
11887db96d56Sopenharmony_cistatic HANDLE
11897db96d56Sopenharmony_ci_winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle,
11907db96d56Sopenharmony_ci                             HANDLE source_handle,
11917db96d56Sopenharmony_ci                             HANDLE target_process_handle,
11927db96d56Sopenharmony_ci                             DWORD desired_access, BOOL inherit_handle,
11937db96d56Sopenharmony_ci                             DWORD options)
11947db96d56Sopenharmony_ci/*[clinic end generated code: output=ad9711397b5dcd4e input=b933e3f2356a8c12]*/
11957db96d56Sopenharmony_ci{
11967db96d56Sopenharmony_ci    HANDLE target_handle;
11977db96d56Sopenharmony_ci    BOOL result;
11987db96d56Sopenharmony_ci
11997db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
12007db96d56Sopenharmony_ci    result = DuplicateHandle(
12017db96d56Sopenharmony_ci        source_process_handle,
12027db96d56Sopenharmony_ci        source_handle,
12037db96d56Sopenharmony_ci        target_process_handle,
12047db96d56Sopenharmony_ci        &target_handle,
12057db96d56Sopenharmony_ci        desired_access,
12067db96d56Sopenharmony_ci        inherit_handle,
12077db96d56Sopenharmony_ci        options
12087db96d56Sopenharmony_ci    );
12097db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
12107db96d56Sopenharmony_ci
12117db96d56Sopenharmony_ci    if (! result) {
12127db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(GetLastError());
12137db96d56Sopenharmony_ci        return INVALID_HANDLE_VALUE;
12147db96d56Sopenharmony_ci    }
12157db96d56Sopenharmony_ci
12167db96d56Sopenharmony_ci    return target_handle;
12177db96d56Sopenharmony_ci}
12187db96d56Sopenharmony_ci
12197db96d56Sopenharmony_ci/*[clinic input]
12207db96d56Sopenharmony_ci_winapi.ExitProcess
12217db96d56Sopenharmony_ci
12227db96d56Sopenharmony_ci    ExitCode: UINT
12237db96d56Sopenharmony_ci    /
12247db96d56Sopenharmony_ci
12257db96d56Sopenharmony_ci[clinic start generated code]*/
12267db96d56Sopenharmony_ci
12277db96d56Sopenharmony_cistatic PyObject *
12287db96d56Sopenharmony_ci_winapi_ExitProcess_impl(PyObject *module, UINT ExitCode)
12297db96d56Sopenharmony_ci/*[clinic end generated code: output=a387deb651175301 input=4f05466a9406c558]*/
12307db96d56Sopenharmony_ci{
12317db96d56Sopenharmony_ci    #if defined(Py_DEBUG)
12327db96d56Sopenharmony_ci        SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|
12337db96d56Sopenharmony_ci                     SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
12347db96d56Sopenharmony_ci        _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
12357db96d56Sopenharmony_ci    #endif
12367db96d56Sopenharmony_ci
12377db96d56Sopenharmony_ci    ExitProcess(ExitCode);
12387db96d56Sopenharmony_ci
12397db96d56Sopenharmony_ci    return NULL;
12407db96d56Sopenharmony_ci}
12417db96d56Sopenharmony_ci
12427db96d56Sopenharmony_ci/*[clinic input]
12437db96d56Sopenharmony_ci_winapi.GetCurrentProcess -> HANDLE
12447db96d56Sopenharmony_ci
12457db96d56Sopenharmony_ciReturn a handle object for the current process.
12467db96d56Sopenharmony_ci[clinic start generated code]*/
12477db96d56Sopenharmony_ci
12487db96d56Sopenharmony_cistatic HANDLE
12497db96d56Sopenharmony_ci_winapi_GetCurrentProcess_impl(PyObject *module)
12507db96d56Sopenharmony_ci/*[clinic end generated code: output=ddeb4dd2ffadf344 input=b213403fd4b96b41]*/
12517db96d56Sopenharmony_ci{
12527db96d56Sopenharmony_ci    return GetCurrentProcess();
12537db96d56Sopenharmony_ci}
12547db96d56Sopenharmony_ci
12557db96d56Sopenharmony_ci/*[clinic input]
12567db96d56Sopenharmony_ci_winapi.GetExitCodeProcess -> DWORD
12577db96d56Sopenharmony_ci
12587db96d56Sopenharmony_ci    process: HANDLE
12597db96d56Sopenharmony_ci    /
12607db96d56Sopenharmony_ci
12617db96d56Sopenharmony_ciReturn the termination status of the specified process.
12627db96d56Sopenharmony_ci[clinic start generated code]*/
12637db96d56Sopenharmony_ci
12647db96d56Sopenharmony_cistatic DWORD
12657db96d56Sopenharmony_ci_winapi_GetExitCodeProcess_impl(PyObject *module, HANDLE process)
12667db96d56Sopenharmony_ci/*[clinic end generated code: output=b4620bdf2bccf36b input=61b6bfc7dc2ee374]*/
12677db96d56Sopenharmony_ci{
12687db96d56Sopenharmony_ci    DWORD exit_code;
12697db96d56Sopenharmony_ci    BOOL result;
12707db96d56Sopenharmony_ci
12717db96d56Sopenharmony_ci    result = GetExitCodeProcess(process, &exit_code);
12727db96d56Sopenharmony_ci
12737db96d56Sopenharmony_ci    if (! result) {
12747db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(GetLastError());
12757db96d56Sopenharmony_ci        exit_code = PY_DWORD_MAX;
12767db96d56Sopenharmony_ci    }
12777db96d56Sopenharmony_ci
12787db96d56Sopenharmony_ci    return exit_code;
12797db96d56Sopenharmony_ci}
12807db96d56Sopenharmony_ci
12817db96d56Sopenharmony_ci/*[clinic input]
12827db96d56Sopenharmony_ci_winapi.GetLastError -> DWORD
12837db96d56Sopenharmony_ci[clinic start generated code]*/
12847db96d56Sopenharmony_ci
12857db96d56Sopenharmony_cistatic DWORD
12867db96d56Sopenharmony_ci_winapi_GetLastError_impl(PyObject *module)
12877db96d56Sopenharmony_ci/*[clinic end generated code: output=8585b827cb1a92c5 input=62d47fb9bce038ba]*/
12887db96d56Sopenharmony_ci{
12897db96d56Sopenharmony_ci    return GetLastError();
12907db96d56Sopenharmony_ci}
12917db96d56Sopenharmony_ci
12927db96d56Sopenharmony_ci/*[clinic input]
12937db96d56Sopenharmony_ci_winapi.GetModuleFileName
12947db96d56Sopenharmony_ci
12957db96d56Sopenharmony_ci    module_handle: HMODULE
12967db96d56Sopenharmony_ci    /
12977db96d56Sopenharmony_ci
12987db96d56Sopenharmony_ciReturn the fully-qualified path for the file that contains module.
12997db96d56Sopenharmony_ci
13007db96d56Sopenharmony_ciThe module must have been loaded by the current process.
13017db96d56Sopenharmony_ci
13027db96d56Sopenharmony_ciThe module parameter should be a handle to the loaded module
13037db96d56Sopenharmony_ciwhose path is being requested. If this parameter is 0,
13047db96d56Sopenharmony_ciGetModuleFileName retrieves the path of the executable file
13057db96d56Sopenharmony_ciof the current process.
13067db96d56Sopenharmony_ci[clinic start generated code]*/
13077db96d56Sopenharmony_ci
13087db96d56Sopenharmony_cistatic PyObject *
13097db96d56Sopenharmony_ci_winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle)
13107db96d56Sopenharmony_ci/*[clinic end generated code: output=85b4b728c5160306 input=6d66ff7deca5d11f]*/
13117db96d56Sopenharmony_ci{
13127db96d56Sopenharmony_ci    BOOL result;
13137db96d56Sopenharmony_ci    WCHAR filename[MAX_PATH];
13147db96d56Sopenharmony_ci
13157db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
13167db96d56Sopenharmony_ci    result = GetModuleFileNameW(module_handle, filename, MAX_PATH);
13177db96d56Sopenharmony_ci    filename[MAX_PATH-1] = '\0';
13187db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
13197db96d56Sopenharmony_ci
13207db96d56Sopenharmony_ci    if (! result)
13217db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(GetLastError());
13227db96d56Sopenharmony_ci
13237db96d56Sopenharmony_ci    return PyUnicode_FromWideChar(filename, wcslen(filename));
13247db96d56Sopenharmony_ci}
13257db96d56Sopenharmony_ci
13267db96d56Sopenharmony_ci/*[clinic input]
13277db96d56Sopenharmony_ci_winapi.GetStdHandle -> HANDLE
13287db96d56Sopenharmony_ci
13297db96d56Sopenharmony_ci    std_handle: DWORD
13307db96d56Sopenharmony_ci        One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE.
13317db96d56Sopenharmony_ci    /
13327db96d56Sopenharmony_ci
13337db96d56Sopenharmony_ciReturn a handle to the specified standard device.
13347db96d56Sopenharmony_ci
13357db96d56Sopenharmony_ciThe integer associated with the handle object is returned.
13367db96d56Sopenharmony_ci[clinic start generated code]*/
13377db96d56Sopenharmony_ci
13387db96d56Sopenharmony_cistatic HANDLE
13397db96d56Sopenharmony_ci_winapi_GetStdHandle_impl(PyObject *module, DWORD std_handle)
13407db96d56Sopenharmony_ci/*[clinic end generated code: output=0e613001e73ab614 input=07016b06a2fc8826]*/
13417db96d56Sopenharmony_ci{
13427db96d56Sopenharmony_ci    HANDLE handle;
13437db96d56Sopenharmony_ci
13447db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
13457db96d56Sopenharmony_ci    handle = GetStdHandle(std_handle);
13467db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
13477db96d56Sopenharmony_ci
13487db96d56Sopenharmony_ci    if (handle == INVALID_HANDLE_VALUE)
13497db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(GetLastError());
13507db96d56Sopenharmony_ci
13517db96d56Sopenharmony_ci    return handle;
13527db96d56Sopenharmony_ci}
13537db96d56Sopenharmony_ci
13547db96d56Sopenharmony_ci/*[clinic input]
13557db96d56Sopenharmony_ci_winapi.GetVersion -> long
13567db96d56Sopenharmony_ci
13577db96d56Sopenharmony_ciReturn the version number of the current operating system.
13587db96d56Sopenharmony_ci[clinic start generated code]*/
13597db96d56Sopenharmony_ci
13607db96d56Sopenharmony_cistatic long
13617db96d56Sopenharmony_ci_winapi_GetVersion_impl(PyObject *module)
13627db96d56Sopenharmony_ci/*[clinic end generated code: output=e41f0db5a3b82682 input=e21dff8d0baeded2]*/
13637db96d56Sopenharmony_ci/* Disable deprecation warnings about GetVersionEx as the result is
13647db96d56Sopenharmony_ci   being passed straight through to the caller, who is responsible for
13657db96d56Sopenharmony_ci   using it correctly. */
13667db96d56Sopenharmony_ci#pragma warning(push)
13677db96d56Sopenharmony_ci#pragma warning(disable:4996)
13687db96d56Sopenharmony_ci
13697db96d56Sopenharmony_ci{
13707db96d56Sopenharmony_ci    return GetVersion();
13717db96d56Sopenharmony_ci}
13727db96d56Sopenharmony_ci
13737db96d56Sopenharmony_ci#pragma warning(pop)
13747db96d56Sopenharmony_ci
13757db96d56Sopenharmony_ci/*[clinic input]
13767db96d56Sopenharmony_ci_winapi.MapViewOfFile -> LPVOID
13777db96d56Sopenharmony_ci
13787db96d56Sopenharmony_ci    file_map: HANDLE
13797db96d56Sopenharmony_ci    desired_access: DWORD
13807db96d56Sopenharmony_ci    file_offset_high: DWORD
13817db96d56Sopenharmony_ci    file_offset_low: DWORD
13827db96d56Sopenharmony_ci    number_bytes: size_t
13837db96d56Sopenharmony_ci    /
13847db96d56Sopenharmony_ci[clinic start generated code]*/
13857db96d56Sopenharmony_ci
13867db96d56Sopenharmony_cistatic LPVOID
13877db96d56Sopenharmony_ci_winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map,
13887db96d56Sopenharmony_ci                           DWORD desired_access, DWORD file_offset_high,
13897db96d56Sopenharmony_ci                           DWORD file_offset_low, size_t number_bytes)
13907db96d56Sopenharmony_ci/*[clinic end generated code: output=f23b1ee4823663e3 input=177471073be1a103]*/
13917db96d56Sopenharmony_ci{
13927db96d56Sopenharmony_ci    LPVOID address;
13937db96d56Sopenharmony_ci
13947db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
13957db96d56Sopenharmony_ci    address = MapViewOfFile(file_map, desired_access, file_offset_high,
13967db96d56Sopenharmony_ci                            file_offset_low, number_bytes);
13977db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
13987db96d56Sopenharmony_ci
13997db96d56Sopenharmony_ci    if (address == NULL)
14007db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(0);
14017db96d56Sopenharmony_ci
14027db96d56Sopenharmony_ci    return address;
14037db96d56Sopenharmony_ci}
14047db96d56Sopenharmony_ci
14057db96d56Sopenharmony_ci/*[clinic input]
14067db96d56Sopenharmony_ci_winapi.UnmapViewOfFile
14077db96d56Sopenharmony_ci
14087db96d56Sopenharmony_ci    address: LPCVOID
14097db96d56Sopenharmony_ci    /
14107db96d56Sopenharmony_ci[clinic start generated code]*/
14117db96d56Sopenharmony_ci
14127db96d56Sopenharmony_cistatic PyObject *
14137db96d56Sopenharmony_ci_winapi_UnmapViewOfFile_impl(PyObject *module, LPCVOID address)
14147db96d56Sopenharmony_ci/*[clinic end generated code: output=4f7e18ac75d19744 input=8c4b6119ad9288a3]*/
14157db96d56Sopenharmony_ci{
14167db96d56Sopenharmony_ci    BOOL success;
14177db96d56Sopenharmony_ci
14187db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
14197db96d56Sopenharmony_ci    success = UnmapViewOfFile(address);
14207db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
14217db96d56Sopenharmony_ci
14227db96d56Sopenharmony_ci    if (!success) {
14237db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(0);
14247db96d56Sopenharmony_ci    }
14257db96d56Sopenharmony_ci
14267db96d56Sopenharmony_ci    Py_RETURN_NONE;
14277db96d56Sopenharmony_ci}
14287db96d56Sopenharmony_ci
14297db96d56Sopenharmony_ci/*[clinic input]
14307db96d56Sopenharmony_ci_winapi.OpenFileMapping -> HANDLE
14317db96d56Sopenharmony_ci
14327db96d56Sopenharmony_ci    desired_access: DWORD
14337db96d56Sopenharmony_ci    inherit_handle: BOOL
14347db96d56Sopenharmony_ci    name: LPCWSTR
14357db96d56Sopenharmony_ci    /
14367db96d56Sopenharmony_ci[clinic start generated code]*/
14377db96d56Sopenharmony_ci
14387db96d56Sopenharmony_cistatic HANDLE
14397db96d56Sopenharmony_ci_winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access,
14407db96d56Sopenharmony_ci                             BOOL inherit_handle, LPCWSTR name)
14417db96d56Sopenharmony_ci/*[clinic end generated code: output=08cc44def1cb11f1 input=131f2a405359de7f]*/
14427db96d56Sopenharmony_ci{
14437db96d56Sopenharmony_ci    HANDLE handle;
14447db96d56Sopenharmony_ci
14457db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
14467db96d56Sopenharmony_ci    handle = OpenFileMappingW(desired_access, inherit_handle, name);
14477db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
14487db96d56Sopenharmony_ci
14497db96d56Sopenharmony_ci    if (handle == NULL) {
14507db96d56Sopenharmony_ci        PyObject *temp = PyUnicode_FromWideChar(name, -1);
14517db96d56Sopenharmony_ci        PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp);
14527db96d56Sopenharmony_ci        Py_XDECREF(temp);
14537db96d56Sopenharmony_ci        handle = INVALID_HANDLE_VALUE;
14547db96d56Sopenharmony_ci    }
14557db96d56Sopenharmony_ci
14567db96d56Sopenharmony_ci    return handle;
14577db96d56Sopenharmony_ci}
14587db96d56Sopenharmony_ci
14597db96d56Sopenharmony_ci/*[clinic input]
14607db96d56Sopenharmony_ci_winapi.OpenProcess -> HANDLE
14617db96d56Sopenharmony_ci
14627db96d56Sopenharmony_ci    desired_access: DWORD
14637db96d56Sopenharmony_ci    inherit_handle: BOOL
14647db96d56Sopenharmony_ci    process_id: DWORD
14657db96d56Sopenharmony_ci    /
14667db96d56Sopenharmony_ci[clinic start generated code]*/
14677db96d56Sopenharmony_ci
14687db96d56Sopenharmony_cistatic HANDLE
14697db96d56Sopenharmony_ci_winapi_OpenProcess_impl(PyObject *module, DWORD desired_access,
14707db96d56Sopenharmony_ci                         BOOL inherit_handle, DWORD process_id)
14717db96d56Sopenharmony_ci/*[clinic end generated code: output=b42b6b81ea5a0fc3 input=ec98c4cf4ea2ec36]*/
14727db96d56Sopenharmony_ci{
14737db96d56Sopenharmony_ci    HANDLE handle;
14747db96d56Sopenharmony_ci
14757db96d56Sopenharmony_ci    if (PySys_Audit("_winapi.OpenProcess", "II",
14767db96d56Sopenharmony_ci                    process_id, desired_access) < 0) {
14777db96d56Sopenharmony_ci        return INVALID_HANDLE_VALUE;
14787db96d56Sopenharmony_ci    }
14797db96d56Sopenharmony_ci
14807db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
14817db96d56Sopenharmony_ci    handle = OpenProcess(desired_access, inherit_handle, process_id);
14827db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
14837db96d56Sopenharmony_ci    if (handle == NULL) {
14847db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(GetLastError());
14857db96d56Sopenharmony_ci        handle = INVALID_HANDLE_VALUE;
14867db96d56Sopenharmony_ci    }
14877db96d56Sopenharmony_ci
14887db96d56Sopenharmony_ci    return handle;
14897db96d56Sopenharmony_ci}
14907db96d56Sopenharmony_ci
14917db96d56Sopenharmony_ci/*[clinic input]
14927db96d56Sopenharmony_ci_winapi.PeekNamedPipe
14937db96d56Sopenharmony_ci
14947db96d56Sopenharmony_ci    handle: HANDLE
14957db96d56Sopenharmony_ci    size: int = 0
14967db96d56Sopenharmony_ci    /
14977db96d56Sopenharmony_ci[clinic start generated code]*/
14987db96d56Sopenharmony_ci
14997db96d56Sopenharmony_cistatic PyObject *
15007db96d56Sopenharmony_ci_winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size)
15017db96d56Sopenharmony_ci/*[clinic end generated code: output=d0c3e29e49d323dd input=c7aa53bfbce69d70]*/
15027db96d56Sopenharmony_ci{
15037db96d56Sopenharmony_ci    PyObject *buf = NULL;
15047db96d56Sopenharmony_ci    DWORD nread, navail, nleft;
15057db96d56Sopenharmony_ci    BOOL ret;
15067db96d56Sopenharmony_ci
15077db96d56Sopenharmony_ci    if (size < 0) {
15087db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "negative size");
15097db96d56Sopenharmony_ci        return NULL;
15107db96d56Sopenharmony_ci    }
15117db96d56Sopenharmony_ci
15127db96d56Sopenharmony_ci    if (size) {
15137db96d56Sopenharmony_ci        buf = PyBytes_FromStringAndSize(NULL, size);
15147db96d56Sopenharmony_ci        if (!buf)
15157db96d56Sopenharmony_ci            return NULL;
15167db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
15177db96d56Sopenharmony_ci        ret = PeekNamedPipe(handle, PyBytes_AS_STRING(buf), size, &nread,
15187db96d56Sopenharmony_ci                            &navail, &nleft);
15197db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
15207db96d56Sopenharmony_ci        if (!ret) {
15217db96d56Sopenharmony_ci            Py_DECREF(buf);
15227db96d56Sopenharmony_ci            return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
15237db96d56Sopenharmony_ci        }
15247db96d56Sopenharmony_ci        if (_PyBytes_Resize(&buf, nread))
15257db96d56Sopenharmony_ci            return NULL;
15267db96d56Sopenharmony_ci        return Py_BuildValue("NII", buf, navail, nleft);
15277db96d56Sopenharmony_ci    }
15287db96d56Sopenharmony_ci    else {
15297db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
15307db96d56Sopenharmony_ci        ret = PeekNamedPipe(handle, NULL, 0, NULL, &navail, &nleft);
15317db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
15327db96d56Sopenharmony_ci        if (!ret) {
15337db96d56Sopenharmony_ci            return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
15347db96d56Sopenharmony_ci        }
15357db96d56Sopenharmony_ci        return Py_BuildValue("II", navail, nleft);
15367db96d56Sopenharmony_ci    }
15377db96d56Sopenharmony_ci}
15387db96d56Sopenharmony_ci
15397db96d56Sopenharmony_ci/*[clinic input]
15407db96d56Sopenharmony_ci_winapi.LCMapStringEx
15417db96d56Sopenharmony_ci
15427db96d56Sopenharmony_ci    locale: unicode
15437db96d56Sopenharmony_ci    flags: DWORD
15447db96d56Sopenharmony_ci    src: unicode
15457db96d56Sopenharmony_ci
15467db96d56Sopenharmony_ci[clinic start generated code]*/
15477db96d56Sopenharmony_ci
15487db96d56Sopenharmony_cistatic PyObject *
15497db96d56Sopenharmony_ci_winapi_LCMapStringEx_impl(PyObject *module, PyObject *locale, DWORD flags,
15507db96d56Sopenharmony_ci                           PyObject *src)
15517db96d56Sopenharmony_ci/*[clinic end generated code: output=8ea4c9d85a4a1f23 input=2fa6ebc92591731b]*/
15527db96d56Sopenharmony_ci{
15537db96d56Sopenharmony_ci    if (flags & (LCMAP_SORTHANDLE | LCMAP_HASH | LCMAP_BYTEREV |
15547db96d56Sopenharmony_ci                 LCMAP_SORTKEY)) {
15557db96d56Sopenharmony_ci        return PyErr_Format(PyExc_ValueError, "unsupported flags");
15567db96d56Sopenharmony_ci    }
15577db96d56Sopenharmony_ci
15587db96d56Sopenharmony_ci    wchar_t *locale_ = PyUnicode_AsWideCharString(locale, NULL);
15597db96d56Sopenharmony_ci    if (!locale_) {
15607db96d56Sopenharmony_ci        return NULL;
15617db96d56Sopenharmony_ci    }
15627db96d56Sopenharmony_ci    Py_ssize_t srcLenAsSsize;
15637db96d56Sopenharmony_ci    int srcLen;
15647db96d56Sopenharmony_ci    wchar_t *src_ = PyUnicode_AsWideCharString(src, &srcLenAsSsize);
15657db96d56Sopenharmony_ci    if (!src_) {
15667db96d56Sopenharmony_ci        PyMem_Free(locale_);
15677db96d56Sopenharmony_ci        return NULL;
15687db96d56Sopenharmony_ci    }
15697db96d56Sopenharmony_ci    srcLen = (int)srcLenAsSsize;
15707db96d56Sopenharmony_ci    if (srcLen != srcLenAsSsize) {
15717db96d56Sopenharmony_ci        srcLen = -1;
15727db96d56Sopenharmony_ci    }
15737db96d56Sopenharmony_ci
15747db96d56Sopenharmony_ci    int dest_size = LCMapStringEx(locale_, flags, src_, srcLen, NULL, 0,
15757db96d56Sopenharmony_ci                                  NULL, NULL, 0);
15767db96d56Sopenharmony_ci    if (dest_size == 0) {
15777db96d56Sopenharmony_ci        PyMem_Free(locale_);
15787db96d56Sopenharmony_ci        PyMem_Free(src_);
15797db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(0);
15807db96d56Sopenharmony_ci    }
15817db96d56Sopenharmony_ci
15827db96d56Sopenharmony_ci    wchar_t* dest = PyMem_NEW(wchar_t, dest_size);
15837db96d56Sopenharmony_ci    if (dest == NULL) {
15847db96d56Sopenharmony_ci        PyMem_Free(locale_);
15857db96d56Sopenharmony_ci        PyMem_Free(src_);
15867db96d56Sopenharmony_ci        return PyErr_NoMemory();
15877db96d56Sopenharmony_ci    }
15887db96d56Sopenharmony_ci
15897db96d56Sopenharmony_ci    int nmapped = LCMapStringEx(locale_, flags, src_, srcLen, dest, dest_size,
15907db96d56Sopenharmony_ci                                NULL, NULL, 0);
15917db96d56Sopenharmony_ci    if (nmapped == 0) {
15927db96d56Sopenharmony_ci        DWORD error = GetLastError();
15937db96d56Sopenharmony_ci        PyMem_Free(locale_);
15947db96d56Sopenharmony_ci        PyMem_Free(src_);
15957db96d56Sopenharmony_ci        PyMem_DEL(dest);
15967db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(error);
15977db96d56Sopenharmony_ci    }
15987db96d56Sopenharmony_ci
15997db96d56Sopenharmony_ci    PyObject *ret = PyUnicode_FromWideChar(dest, dest_size);
16007db96d56Sopenharmony_ci    PyMem_Free(locale_);
16017db96d56Sopenharmony_ci    PyMem_Free(src_);
16027db96d56Sopenharmony_ci    PyMem_DEL(dest);
16037db96d56Sopenharmony_ci
16047db96d56Sopenharmony_ci    return ret;
16057db96d56Sopenharmony_ci}
16067db96d56Sopenharmony_ci
16077db96d56Sopenharmony_ci/*[clinic input]
16087db96d56Sopenharmony_ci_winapi.ReadFile
16097db96d56Sopenharmony_ci
16107db96d56Sopenharmony_ci    handle: HANDLE
16117db96d56Sopenharmony_ci    size: DWORD
16127db96d56Sopenharmony_ci    overlapped as use_overlapped: bool(accept={int}) = False
16137db96d56Sopenharmony_ci[clinic start generated code]*/
16147db96d56Sopenharmony_ci
16157db96d56Sopenharmony_cistatic PyObject *
16167db96d56Sopenharmony_ci_winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size,
16177db96d56Sopenharmony_ci                      int use_overlapped)
16187db96d56Sopenharmony_ci/*[clinic end generated code: output=d3d5b44a8201b944 input=08c439d03a11aac5]*/
16197db96d56Sopenharmony_ci{
16207db96d56Sopenharmony_ci    DWORD nread;
16217db96d56Sopenharmony_ci    PyObject *buf;
16227db96d56Sopenharmony_ci    BOOL ret;
16237db96d56Sopenharmony_ci    DWORD err;
16247db96d56Sopenharmony_ci    OverlappedObject *overlapped = NULL;
16257db96d56Sopenharmony_ci
16267db96d56Sopenharmony_ci    buf = PyBytes_FromStringAndSize(NULL, size);
16277db96d56Sopenharmony_ci    if (!buf)
16287db96d56Sopenharmony_ci        return NULL;
16297db96d56Sopenharmony_ci    if (use_overlapped) {
16307db96d56Sopenharmony_ci        overlapped = new_overlapped(module, handle);
16317db96d56Sopenharmony_ci        if (!overlapped) {
16327db96d56Sopenharmony_ci            Py_DECREF(buf);
16337db96d56Sopenharmony_ci            return NULL;
16347db96d56Sopenharmony_ci        }
16357db96d56Sopenharmony_ci        /* Steals reference to buf */
16367db96d56Sopenharmony_ci        overlapped->read_buffer = buf;
16377db96d56Sopenharmony_ci    }
16387db96d56Sopenharmony_ci
16397db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
16407db96d56Sopenharmony_ci    ret = ReadFile(handle, PyBytes_AS_STRING(buf), size, &nread,
16417db96d56Sopenharmony_ci                   overlapped ? &overlapped->overlapped : NULL);
16427db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
16437db96d56Sopenharmony_ci
16447db96d56Sopenharmony_ci    err = ret ? 0 : GetLastError();
16457db96d56Sopenharmony_ci
16467db96d56Sopenharmony_ci    if (overlapped) {
16477db96d56Sopenharmony_ci        if (!ret) {
16487db96d56Sopenharmony_ci            if (err == ERROR_IO_PENDING)
16497db96d56Sopenharmony_ci                overlapped->pending = 1;
16507db96d56Sopenharmony_ci            else if (err != ERROR_MORE_DATA) {
16517db96d56Sopenharmony_ci                Py_DECREF(overlapped);
16527db96d56Sopenharmony_ci                return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
16537db96d56Sopenharmony_ci            }
16547db96d56Sopenharmony_ci        }
16557db96d56Sopenharmony_ci        return Py_BuildValue("NI", (PyObject *) overlapped, err);
16567db96d56Sopenharmony_ci    }
16577db96d56Sopenharmony_ci
16587db96d56Sopenharmony_ci    if (!ret && err != ERROR_MORE_DATA) {
16597db96d56Sopenharmony_ci        Py_DECREF(buf);
16607db96d56Sopenharmony_ci        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
16617db96d56Sopenharmony_ci    }
16627db96d56Sopenharmony_ci    if (_PyBytes_Resize(&buf, nread))
16637db96d56Sopenharmony_ci        return NULL;
16647db96d56Sopenharmony_ci    return Py_BuildValue("NI", buf, err);
16657db96d56Sopenharmony_ci}
16667db96d56Sopenharmony_ci
16677db96d56Sopenharmony_ci/*[clinic input]
16687db96d56Sopenharmony_ci_winapi.SetNamedPipeHandleState
16697db96d56Sopenharmony_ci
16707db96d56Sopenharmony_ci    named_pipe: HANDLE
16717db96d56Sopenharmony_ci    mode: object
16727db96d56Sopenharmony_ci    max_collection_count: object
16737db96d56Sopenharmony_ci    collect_data_timeout: object
16747db96d56Sopenharmony_ci    /
16757db96d56Sopenharmony_ci[clinic start generated code]*/
16767db96d56Sopenharmony_ci
16777db96d56Sopenharmony_cistatic PyObject *
16787db96d56Sopenharmony_ci_winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe,
16797db96d56Sopenharmony_ci                                     PyObject *mode,
16807db96d56Sopenharmony_ci                                     PyObject *max_collection_count,
16817db96d56Sopenharmony_ci                                     PyObject *collect_data_timeout)
16827db96d56Sopenharmony_ci/*[clinic end generated code: output=f2129d222cbfa095 input=9142d72163d0faa6]*/
16837db96d56Sopenharmony_ci{
16847db96d56Sopenharmony_ci    PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout};
16857db96d56Sopenharmony_ci    DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
16867db96d56Sopenharmony_ci    int i;
16877db96d56Sopenharmony_ci    BOOL b;
16887db96d56Sopenharmony_ci
16897db96d56Sopenharmony_ci    for (i = 0 ; i < 3 ; i++) {
16907db96d56Sopenharmony_ci        if (oArgs[i] != Py_None) {
16917db96d56Sopenharmony_ci            dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
16927db96d56Sopenharmony_ci            if (PyErr_Occurred())
16937db96d56Sopenharmony_ci                return NULL;
16947db96d56Sopenharmony_ci            pArgs[i] = &dwArgs[i];
16957db96d56Sopenharmony_ci        }
16967db96d56Sopenharmony_ci    }
16977db96d56Sopenharmony_ci
16987db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
16997db96d56Sopenharmony_ci    b = SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2]);
17007db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
17017db96d56Sopenharmony_ci
17027db96d56Sopenharmony_ci    if (!b)
17037db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(0);
17047db96d56Sopenharmony_ci
17057db96d56Sopenharmony_ci    Py_RETURN_NONE;
17067db96d56Sopenharmony_ci}
17077db96d56Sopenharmony_ci
17087db96d56Sopenharmony_ci
17097db96d56Sopenharmony_ci/*[clinic input]
17107db96d56Sopenharmony_ci_winapi.TerminateProcess
17117db96d56Sopenharmony_ci
17127db96d56Sopenharmony_ci    handle: HANDLE
17137db96d56Sopenharmony_ci    exit_code: UINT
17147db96d56Sopenharmony_ci    /
17157db96d56Sopenharmony_ci
17167db96d56Sopenharmony_ciTerminate the specified process and all of its threads.
17177db96d56Sopenharmony_ci[clinic start generated code]*/
17187db96d56Sopenharmony_ci
17197db96d56Sopenharmony_cistatic PyObject *
17207db96d56Sopenharmony_ci_winapi_TerminateProcess_impl(PyObject *module, HANDLE handle,
17217db96d56Sopenharmony_ci                              UINT exit_code)
17227db96d56Sopenharmony_ci/*[clinic end generated code: output=f4e99ac3f0b1f34a input=d6bc0aa1ee3bb4df]*/
17237db96d56Sopenharmony_ci{
17247db96d56Sopenharmony_ci    BOOL result;
17257db96d56Sopenharmony_ci
17267db96d56Sopenharmony_ci    if (PySys_Audit("_winapi.TerminateProcess", "nI",
17277db96d56Sopenharmony_ci                    (Py_ssize_t)handle, exit_code) < 0) {
17287db96d56Sopenharmony_ci        return NULL;
17297db96d56Sopenharmony_ci    }
17307db96d56Sopenharmony_ci
17317db96d56Sopenharmony_ci    result = TerminateProcess(handle, exit_code);
17327db96d56Sopenharmony_ci
17337db96d56Sopenharmony_ci    if (! result)
17347db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(GetLastError());
17357db96d56Sopenharmony_ci
17367db96d56Sopenharmony_ci    Py_RETURN_NONE;
17377db96d56Sopenharmony_ci}
17387db96d56Sopenharmony_ci
17397db96d56Sopenharmony_ci/*[clinic input]
17407db96d56Sopenharmony_ci_winapi.VirtualQuerySize -> size_t
17417db96d56Sopenharmony_ci
17427db96d56Sopenharmony_ci    address: LPCVOID
17437db96d56Sopenharmony_ci    /
17447db96d56Sopenharmony_ci[clinic start generated code]*/
17457db96d56Sopenharmony_ci
17467db96d56Sopenharmony_cistatic size_t
17477db96d56Sopenharmony_ci_winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address)
17487db96d56Sopenharmony_ci/*[clinic end generated code: output=40c8e0ff5ec964df input=6b784a69755d0bb6]*/
17497db96d56Sopenharmony_ci{
17507db96d56Sopenharmony_ci    SIZE_T size_of_buf;
17517db96d56Sopenharmony_ci    MEMORY_BASIC_INFORMATION mem_basic_info;
17527db96d56Sopenharmony_ci    SIZE_T region_size;
17537db96d56Sopenharmony_ci
17547db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
17557db96d56Sopenharmony_ci    size_of_buf = VirtualQuery(address, &mem_basic_info, sizeof(mem_basic_info));
17567db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
17577db96d56Sopenharmony_ci
17587db96d56Sopenharmony_ci    if (size_of_buf == 0)
17597db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(0);
17607db96d56Sopenharmony_ci
17617db96d56Sopenharmony_ci    region_size = mem_basic_info.RegionSize;
17627db96d56Sopenharmony_ci    return region_size;
17637db96d56Sopenharmony_ci}
17647db96d56Sopenharmony_ci
17657db96d56Sopenharmony_ci/*[clinic input]
17667db96d56Sopenharmony_ci_winapi.WaitNamedPipe
17677db96d56Sopenharmony_ci
17687db96d56Sopenharmony_ci    name: LPCTSTR
17697db96d56Sopenharmony_ci    timeout: DWORD
17707db96d56Sopenharmony_ci    /
17717db96d56Sopenharmony_ci[clinic start generated code]*/
17727db96d56Sopenharmony_ci
17737db96d56Sopenharmony_cistatic PyObject *
17747db96d56Sopenharmony_ci_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout)
17757db96d56Sopenharmony_ci/*[clinic end generated code: output=c2866f4439b1fe38 input=36fc781291b1862c]*/
17767db96d56Sopenharmony_ci{
17777db96d56Sopenharmony_ci    BOOL success;
17787db96d56Sopenharmony_ci
17797db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
17807db96d56Sopenharmony_ci    success = WaitNamedPipe(name, timeout);
17817db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
17827db96d56Sopenharmony_ci
17837db96d56Sopenharmony_ci    if (!success)
17847db96d56Sopenharmony_ci        return PyErr_SetFromWindowsErr(0);
17857db96d56Sopenharmony_ci
17867db96d56Sopenharmony_ci    Py_RETURN_NONE;
17877db96d56Sopenharmony_ci}
17887db96d56Sopenharmony_ci
17897db96d56Sopenharmony_ci/*[clinic input]
17907db96d56Sopenharmony_ci_winapi.WaitForMultipleObjects
17917db96d56Sopenharmony_ci
17927db96d56Sopenharmony_ci    handle_seq: object
17937db96d56Sopenharmony_ci    wait_flag: BOOL
17947db96d56Sopenharmony_ci    milliseconds: DWORD(c_default='INFINITE') = _winapi.INFINITE
17957db96d56Sopenharmony_ci    /
17967db96d56Sopenharmony_ci[clinic start generated code]*/
17977db96d56Sopenharmony_ci
17987db96d56Sopenharmony_cistatic PyObject *
17997db96d56Sopenharmony_ci_winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq,
18007db96d56Sopenharmony_ci                                    BOOL wait_flag, DWORD milliseconds)
18017db96d56Sopenharmony_ci/*[clinic end generated code: output=295e3f00b8e45899 input=36f76ca057cd28a0]*/
18027db96d56Sopenharmony_ci{
18037db96d56Sopenharmony_ci    DWORD result;
18047db96d56Sopenharmony_ci    HANDLE handles[MAXIMUM_WAIT_OBJECTS];
18057db96d56Sopenharmony_ci    HANDLE sigint_event = NULL;
18067db96d56Sopenharmony_ci    Py_ssize_t nhandles, i;
18077db96d56Sopenharmony_ci
18087db96d56Sopenharmony_ci    if (!PySequence_Check(handle_seq)) {
18097db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
18107db96d56Sopenharmony_ci                     "sequence type expected, got '%s'",
18117db96d56Sopenharmony_ci                     Py_TYPE(handle_seq)->tp_name);
18127db96d56Sopenharmony_ci        return NULL;
18137db96d56Sopenharmony_ci    }
18147db96d56Sopenharmony_ci    nhandles = PySequence_Length(handle_seq);
18157db96d56Sopenharmony_ci    if (nhandles == -1)
18167db96d56Sopenharmony_ci        return NULL;
18177db96d56Sopenharmony_ci    if (nhandles < 0 || nhandles > MAXIMUM_WAIT_OBJECTS - 1) {
18187db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError,
18197db96d56Sopenharmony_ci                     "need at most %zd handles, got a sequence of length %zd",
18207db96d56Sopenharmony_ci                     MAXIMUM_WAIT_OBJECTS - 1, nhandles);
18217db96d56Sopenharmony_ci        return NULL;
18227db96d56Sopenharmony_ci    }
18237db96d56Sopenharmony_ci    for (i = 0; i < nhandles; i++) {
18247db96d56Sopenharmony_ci        HANDLE h;
18257db96d56Sopenharmony_ci        PyObject *v = PySequence_GetItem(handle_seq, i);
18267db96d56Sopenharmony_ci        if (v == NULL)
18277db96d56Sopenharmony_ci            return NULL;
18287db96d56Sopenharmony_ci        if (!PyArg_Parse(v, F_HANDLE, &h)) {
18297db96d56Sopenharmony_ci            Py_DECREF(v);
18307db96d56Sopenharmony_ci            return NULL;
18317db96d56Sopenharmony_ci        }
18327db96d56Sopenharmony_ci        handles[i] = h;
18337db96d56Sopenharmony_ci        Py_DECREF(v);
18347db96d56Sopenharmony_ci    }
18357db96d56Sopenharmony_ci    /* If this is the main thread then make the wait interruptible
18367db96d56Sopenharmony_ci       by Ctrl-C unless we are waiting for *all* handles */
18377db96d56Sopenharmony_ci    if (!wait_flag && _PyOS_IsMainThread()) {
18387db96d56Sopenharmony_ci        sigint_event = _PyOS_SigintEvent();
18397db96d56Sopenharmony_ci        assert(sigint_event != NULL);
18407db96d56Sopenharmony_ci        handles[nhandles++] = sigint_event;
18417db96d56Sopenharmony_ci    }
18427db96d56Sopenharmony_ci
18437db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
18447db96d56Sopenharmony_ci    if (sigint_event != NULL)
18457db96d56Sopenharmony_ci        ResetEvent(sigint_event);
18467db96d56Sopenharmony_ci    result = WaitForMultipleObjects((DWORD) nhandles, handles,
18477db96d56Sopenharmony_ci                                    wait_flag, milliseconds);
18487db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
18497db96d56Sopenharmony_ci
18507db96d56Sopenharmony_ci    if (result == WAIT_FAILED)
18517db96d56Sopenharmony_ci        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
18527db96d56Sopenharmony_ci    else if (sigint_event != NULL && result == WAIT_OBJECT_0 + nhandles - 1) {
18537db96d56Sopenharmony_ci        errno = EINTR;
18547db96d56Sopenharmony_ci        return PyErr_SetFromErrno(PyExc_OSError);
18557db96d56Sopenharmony_ci    }
18567db96d56Sopenharmony_ci
18577db96d56Sopenharmony_ci    return PyLong_FromLong((int) result);
18587db96d56Sopenharmony_ci}
18597db96d56Sopenharmony_ci
18607db96d56Sopenharmony_ci/*[clinic input]
18617db96d56Sopenharmony_ci_winapi.WaitForSingleObject -> long
18627db96d56Sopenharmony_ci
18637db96d56Sopenharmony_ci    handle: HANDLE
18647db96d56Sopenharmony_ci    milliseconds: DWORD
18657db96d56Sopenharmony_ci    /
18667db96d56Sopenharmony_ci
18677db96d56Sopenharmony_ciWait for a single object.
18687db96d56Sopenharmony_ci
18697db96d56Sopenharmony_ciWait until the specified object is in the signaled state or
18707db96d56Sopenharmony_cithe time-out interval elapses. The timeout value is specified
18717db96d56Sopenharmony_ciin milliseconds.
18727db96d56Sopenharmony_ci[clinic start generated code]*/
18737db96d56Sopenharmony_ci
18747db96d56Sopenharmony_cistatic long
18757db96d56Sopenharmony_ci_winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle,
18767db96d56Sopenharmony_ci                                 DWORD milliseconds)
18777db96d56Sopenharmony_ci/*[clinic end generated code: output=3c4715d8f1b39859 input=443d1ab076edc7b1]*/
18787db96d56Sopenharmony_ci{
18797db96d56Sopenharmony_ci    DWORD result;
18807db96d56Sopenharmony_ci
18817db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
18827db96d56Sopenharmony_ci    result = WaitForSingleObject(handle, milliseconds);
18837db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
18847db96d56Sopenharmony_ci
18857db96d56Sopenharmony_ci    if (result == WAIT_FAILED) {
18867db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(GetLastError());
18877db96d56Sopenharmony_ci        return -1;
18887db96d56Sopenharmony_ci    }
18897db96d56Sopenharmony_ci
18907db96d56Sopenharmony_ci    return result;
18917db96d56Sopenharmony_ci}
18927db96d56Sopenharmony_ci
18937db96d56Sopenharmony_ci/*[clinic input]
18947db96d56Sopenharmony_ci_winapi.WriteFile
18957db96d56Sopenharmony_ci
18967db96d56Sopenharmony_ci    handle: HANDLE
18977db96d56Sopenharmony_ci    buffer: object
18987db96d56Sopenharmony_ci    overlapped as use_overlapped: bool(accept={int}) = False
18997db96d56Sopenharmony_ci[clinic start generated code]*/
19007db96d56Sopenharmony_ci
19017db96d56Sopenharmony_cistatic PyObject *
19027db96d56Sopenharmony_ci_winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer,
19037db96d56Sopenharmony_ci                       int use_overlapped)
19047db96d56Sopenharmony_ci/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=11eae2a03aa32731]*/
19057db96d56Sopenharmony_ci{
19067db96d56Sopenharmony_ci    Py_buffer _buf, *buf;
19077db96d56Sopenharmony_ci    DWORD len, written;
19087db96d56Sopenharmony_ci    BOOL ret;
19097db96d56Sopenharmony_ci    DWORD err;
19107db96d56Sopenharmony_ci    OverlappedObject *overlapped = NULL;
19117db96d56Sopenharmony_ci
19127db96d56Sopenharmony_ci    if (use_overlapped) {
19137db96d56Sopenharmony_ci        overlapped = new_overlapped(module, handle);
19147db96d56Sopenharmony_ci        if (!overlapped)
19157db96d56Sopenharmony_ci            return NULL;
19167db96d56Sopenharmony_ci        buf = &overlapped->write_buffer;
19177db96d56Sopenharmony_ci    }
19187db96d56Sopenharmony_ci    else
19197db96d56Sopenharmony_ci        buf = &_buf;
19207db96d56Sopenharmony_ci
19217db96d56Sopenharmony_ci    if (!PyArg_Parse(buffer, "y*", buf)) {
19227db96d56Sopenharmony_ci        Py_XDECREF(overlapped);
19237db96d56Sopenharmony_ci        return NULL;
19247db96d56Sopenharmony_ci    }
19257db96d56Sopenharmony_ci
19267db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
19277db96d56Sopenharmony_ci    len = (DWORD)Py_MIN(buf->len, PY_DWORD_MAX);
19287db96d56Sopenharmony_ci    ret = WriteFile(handle, buf->buf, len, &written,
19297db96d56Sopenharmony_ci                    overlapped ? &overlapped->overlapped : NULL);
19307db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
19317db96d56Sopenharmony_ci
19327db96d56Sopenharmony_ci    err = ret ? 0 : GetLastError();
19337db96d56Sopenharmony_ci
19347db96d56Sopenharmony_ci    if (overlapped) {
19357db96d56Sopenharmony_ci        if (!ret) {
19367db96d56Sopenharmony_ci            if (err == ERROR_IO_PENDING)
19377db96d56Sopenharmony_ci                overlapped->pending = 1;
19387db96d56Sopenharmony_ci            else {
19397db96d56Sopenharmony_ci                Py_DECREF(overlapped);
19407db96d56Sopenharmony_ci                return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
19417db96d56Sopenharmony_ci            }
19427db96d56Sopenharmony_ci        }
19437db96d56Sopenharmony_ci        return Py_BuildValue("NI", (PyObject *) overlapped, err);
19447db96d56Sopenharmony_ci    }
19457db96d56Sopenharmony_ci
19467db96d56Sopenharmony_ci    PyBuffer_Release(buf);
19477db96d56Sopenharmony_ci    if (!ret)
19487db96d56Sopenharmony_ci        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
19497db96d56Sopenharmony_ci    return Py_BuildValue("II", written, err);
19507db96d56Sopenharmony_ci}
19517db96d56Sopenharmony_ci
19527db96d56Sopenharmony_ci/*[clinic input]
19537db96d56Sopenharmony_ci_winapi.GetACP
19547db96d56Sopenharmony_ci
19557db96d56Sopenharmony_ciGet the current Windows ANSI code page identifier.
19567db96d56Sopenharmony_ci[clinic start generated code]*/
19577db96d56Sopenharmony_ci
19587db96d56Sopenharmony_cistatic PyObject *
19597db96d56Sopenharmony_ci_winapi_GetACP_impl(PyObject *module)
19607db96d56Sopenharmony_ci/*[clinic end generated code: output=f7ee24bf705dbb88 input=1433c96d03a05229]*/
19617db96d56Sopenharmony_ci{
19627db96d56Sopenharmony_ci    return PyLong_FromUnsignedLong(GetACP());
19637db96d56Sopenharmony_ci}
19647db96d56Sopenharmony_ci
19657db96d56Sopenharmony_ci/*[clinic input]
19667db96d56Sopenharmony_ci_winapi.GetFileType -> DWORD
19677db96d56Sopenharmony_ci
19687db96d56Sopenharmony_ci    handle: HANDLE
19697db96d56Sopenharmony_ci[clinic start generated code]*/
19707db96d56Sopenharmony_ci
19717db96d56Sopenharmony_cistatic DWORD
19727db96d56Sopenharmony_ci_winapi_GetFileType_impl(PyObject *module, HANDLE handle)
19737db96d56Sopenharmony_ci/*[clinic end generated code: output=92b8466ac76ecc17 input=0058366bc40bbfbf]*/
19747db96d56Sopenharmony_ci{
19757db96d56Sopenharmony_ci    DWORD result;
19767db96d56Sopenharmony_ci
19777db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
19787db96d56Sopenharmony_ci    result = GetFileType(handle);
19797db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
19807db96d56Sopenharmony_ci
19817db96d56Sopenharmony_ci    if (result == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR) {
19827db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr(0);
19837db96d56Sopenharmony_ci        return -1;
19847db96d56Sopenharmony_ci    }
19857db96d56Sopenharmony_ci
19867db96d56Sopenharmony_ci    return result;
19877db96d56Sopenharmony_ci}
19887db96d56Sopenharmony_ci
19897db96d56Sopenharmony_ci/*[clinic input]
19907db96d56Sopenharmony_ci_winapi._mimetypes_read_windows_registry
19917db96d56Sopenharmony_ci
19927db96d56Sopenharmony_ci    on_type_read: object
19937db96d56Sopenharmony_ci
19947db96d56Sopenharmony_ciOptimized function for reading all known MIME types from the registry.
19957db96d56Sopenharmony_ci
19967db96d56Sopenharmony_ci*on_type_read* is a callable taking *type* and *ext* arguments, as for
19977db96d56Sopenharmony_ciMimeTypes.add_type.
19987db96d56Sopenharmony_ci[clinic start generated code]*/
19997db96d56Sopenharmony_ci
20007db96d56Sopenharmony_cistatic PyObject *
20017db96d56Sopenharmony_ci_winapi__mimetypes_read_windows_registry_impl(PyObject *module,
20027db96d56Sopenharmony_ci                                              PyObject *on_type_read)
20037db96d56Sopenharmony_ci/*[clinic end generated code: output=20829f00bebce55b input=cd357896d6501f68]*/
20047db96d56Sopenharmony_ci{
20057db96d56Sopenharmony_ci#define CCH_EXT 128
20067db96d56Sopenharmony_ci#define CB_TYPE 510
20077db96d56Sopenharmony_ci    struct {
20087db96d56Sopenharmony_ci        wchar_t ext[CCH_EXT];
20097db96d56Sopenharmony_ci        wchar_t type[CB_TYPE / sizeof(wchar_t) + 1];
20107db96d56Sopenharmony_ci    } entries[64];
20117db96d56Sopenharmony_ci    int entry = 0;
20127db96d56Sopenharmony_ci    HKEY hkcr = NULL;
20137db96d56Sopenharmony_ci    LRESULT err;
20147db96d56Sopenharmony_ci
20157db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
20167db96d56Sopenharmony_ci    err = RegOpenKeyExW(HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &hkcr);
20177db96d56Sopenharmony_ci    for (DWORD i = 0; err == ERROR_SUCCESS || err == ERROR_MORE_DATA; ++i) {
20187db96d56Sopenharmony_ci        LPWSTR ext = entries[entry].ext;
20197db96d56Sopenharmony_ci        LPWSTR type = entries[entry].type;
20207db96d56Sopenharmony_ci        DWORD cchExt = CCH_EXT;
20217db96d56Sopenharmony_ci        DWORD cbType = CB_TYPE;
20227db96d56Sopenharmony_ci        HKEY subkey;
20237db96d56Sopenharmony_ci        DWORD regType;
20247db96d56Sopenharmony_ci
20257db96d56Sopenharmony_ci        err = RegEnumKeyExW(hkcr, i, ext, &cchExt, NULL, NULL, NULL, NULL);
20267db96d56Sopenharmony_ci        if (err != ERROR_SUCCESS || (cchExt && ext[0] != L'.')) {
20277db96d56Sopenharmony_ci            continue;
20287db96d56Sopenharmony_ci        }
20297db96d56Sopenharmony_ci
20307db96d56Sopenharmony_ci        err = RegOpenKeyExW(hkcr, ext, 0, KEY_READ, &subkey);
20317db96d56Sopenharmony_ci        if (err == ERROR_FILE_NOT_FOUND) {
20327db96d56Sopenharmony_ci            err = ERROR_SUCCESS;
20337db96d56Sopenharmony_ci            continue;
20347db96d56Sopenharmony_ci        } else if (err != ERROR_SUCCESS) {
20357db96d56Sopenharmony_ci            continue;
20367db96d56Sopenharmony_ci        }
20377db96d56Sopenharmony_ci
20387db96d56Sopenharmony_ci        err = RegQueryValueExW(subkey, L"Content Type", NULL,
20397db96d56Sopenharmony_ci                              &regType, (LPBYTE)type, &cbType);
20407db96d56Sopenharmony_ci        RegCloseKey(subkey);
20417db96d56Sopenharmony_ci        if (err == ERROR_FILE_NOT_FOUND) {
20427db96d56Sopenharmony_ci            err = ERROR_SUCCESS;
20437db96d56Sopenharmony_ci            continue;
20447db96d56Sopenharmony_ci        } else if (err != ERROR_SUCCESS) {
20457db96d56Sopenharmony_ci            continue;
20467db96d56Sopenharmony_ci        } else if (regType != REG_SZ || !cbType) {
20477db96d56Sopenharmony_ci            continue;
20487db96d56Sopenharmony_ci        }
20497db96d56Sopenharmony_ci        type[cbType / sizeof(wchar_t)] = L'\0';
20507db96d56Sopenharmony_ci
20517db96d56Sopenharmony_ci        entry += 1;
20527db96d56Sopenharmony_ci
20537db96d56Sopenharmony_ci        /* Flush our cached entries if we are full */
20547db96d56Sopenharmony_ci        if (entry == sizeof(entries) / sizeof(entries[0])) {
20557db96d56Sopenharmony_ci            Py_BLOCK_THREADS
20567db96d56Sopenharmony_ci            for (int j = 0; j < entry; ++j) {
20577db96d56Sopenharmony_ci                PyObject *r = PyObject_CallFunction(
20587db96d56Sopenharmony_ci                    on_type_read, "uu", entries[j].type, entries[j].ext
20597db96d56Sopenharmony_ci                );
20607db96d56Sopenharmony_ci                if (!r) {
20617db96d56Sopenharmony_ci                    /* We blocked threads, so safe to return from here */
20627db96d56Sopenharmony_ci                    RegCloseKey(hkcr);
20637db96d56Sopenharmony_ci                    return NULL;
20647db96d56Sopenharmony_ci                }
20657db96d56Sopenharmony_ci                Py_DECREF(r);
20667db96d56Sopenharmony_ci            }
20677db96d56Sopenharmony_ci            Py_UNBLOCK_THREADS
20687db96d56Sopenharmony_ci            entry = 0;
20697db96d56Sopenharmony_ci        }
20707db96d56Sopenharmony_ci    }
20717db96d56Sopenharmony_ci    if (hkcr) {
20727db96d56Sopenharmony_ci        RegCloseKey(hkcr);
20737db96d56Sopenharmony_ci    }
20747db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
20757db96d56Sopenharmony_ci
20767db96d56Sopenharmony_ci    if (err != ERROR_SUCCESS && err != ERROR_NO_MORE_ITEMS) {
20777db96d56Sopenharmony_ci        PyErr_SetFromWindowsErr((int)err);
20787db96d56Sopenharmony_ci        return NULL;
20797db96d56Sopenharmony_ci    }
20807db96d56Sopenharmony_ci
20817db96d56Sopenharmony_ci    for (int j = 0; j < entry; ++j) {
20827db96d56Sopenharmony_ci        PyObject *r = PyObject_CallFunction(
20837db96d56Sopenharmony_ci            on_type_read, "uu", entries[j].type, entries[j].ext
20847db96d56Sopenharmony_ci        );
20857db96d56Sopenharmony_ci        if (!r) {
20867db96d56Sopenharmony_ci            return NULL;
20877db96d56Sopenharmony_ci        }
20887db96d56Sopenharmony_ci        Py_DECREF(r);
20897db96d56Sopenharmony_ci    }
20907db96d56Sopenharmony_ci
20917db96d56Sopenharmony_ci    Py_RETURN_NONE;
20927db96d56Sopenharmony_ci#undef CCH_EXT
20937db96d56Sopenharmony_ci#undef CB_TYPE
20947db96d56Sopenharmony_ci}
20957db96d56Sopenharmony_ci
20967db96d56Sopenharmony_ci
20977db96d56Sopenharmony_cistatic PyMethodDef winapi_functions[] = {
20987db96d56Sopenharmony_ci    _WINAPI_CLOSEHANDLE_METHODDEF
20997db96d56Sopenharmony_ci    _WINAPI_CONNECTNAMEDPIPE_METHODDEF
21007db96d56Sopenharmony_ci    _WINAPI_CREATEFILE_METHODDEF
21017db96d56Sopenharmony_ci    _WINAPI_CREATEFILEMAPPING_METHODDEF
21027db96d56Sopenharmony_ci    _WINAPI_CREATENAMEDPIPE_METHODDEF
21037db96d56Sopenharmony_ci    _WINAPI_CREATEPIPE_METHODDEF
21047db96d56Sopenharmony_ci    _WINAPI_CREATEPROCESS_METHODDEF
21057db96d56Sopenharmony_ci    _WINAPI_CREATEJUNCTION_METHODDEF
21067db96d56Sopenharmony_ci    _WINAPI_DUPLICATEHANDLE_METHODDEF
21077db96d56Sopenharmony_ci    _WINAPI_EXITPROCESS_METHODDEF
21087db96d56Sopenharmony_ci    _WINAPI_GETCURRENTPROCESS_METHODDEF
21097db96d56Sopenharmony_ci    _WINAPI_GETEXITCODEPROCESS_METHODDEF
21107db96d56Sopenharmony_ci    _WINAPI_GETLASTERROR_METHODDEF
21117db96d56Sopenharmony_ci    _WINAPI_GETMODULEFILENAME_METHODDEF
21127db96d56Sopenharmony_ci    _WINAPI_GETSTDHANDLE_METHODDEF
21137db96d56Sopenharmony_ci    _WINAPI_GETVERSION_METHODDEF
21147db96d56Sopenharmony_ci    _WINAPI_MAPVIEWOFFILE_METHODDEF
21157db96d56Sopenharmony_ci    _WINAPI_OPENFILEMAPPING_METHODDEF
21167db96d56Sopenharmony_ci    _WINAPI_OPENPROCESS_METHODDEF
21177db96d56Sopenharmony_ci    _WINAPI_PEEKNAMEDPIPE_METHODDEF
21187db96d56Sopenharmony_ci    _WINAPI_LCMAPSTRINGEX_METHODDEF
21197db96d56Sopenharmony_ci    _WINAPI_READFILE_METHODDEF
21207db96d56Sopenharmony_ci    _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF
21217db96d56Sopenharmony_ci    _WINAPI_TERMINATEPROCESS_METHODDEF
21227db96d56Sopenharmony_ci    _WINAPI_UNMAPVIEWOFFILE_METHODDEF
21237db96d56Sopenharmony_ci    _WINAPI_VIRTUALQUERYSIZE_METHODDEF
21247db96d56Sopenharmony_ci    _WINAPI_WAITNAMEDPIPE_METHODDEF
21257db96d56Sopenharmony_ci    _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF
21267db96d56Sopenharmony_ci    _WINAPI_WAITFORSINGLEOBJECT_METHODDEF
21277db96d56Sopenharmony_ci    _WINAPI_WRITEFILE_METHODDEF
21287db96d56Sopenharmony_ci    _WINAPI_GETACP_METHODDEF
21297db96d56Sopenharmony_ci    _WINAPI_GETFILETYPE_METHODDEF
21307db96d56Sopenharmony_ci    _WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF
21317db96d56Sopenharmony_ci    {NULL, NULL}
21327db96d56Sopenharmony_ci};
21337db96d56Sopenharmony_ci
21347db96d56Sopenharmony_ci#define WINAPI_CONSTANT(fmt, con) \
21357db96d56Sopenharmony_ci    do { \
21367db96d56Sopenharmony_ci        PyObject *value = Py_BuildValue(fmt, con); \
21377db96d56Sopenharmony_ci        if (value == NULL) { \
21387db96d56Sopenharmony_ci            return -1; \
21397db96d56Sopenharmony_ci        } \
21407db96d56Sopenharmony_ci        if (PyDict_SetItemString(d, #con, value) < 0) { \
21417db96d56Sopenharmony_ci            Py_DECREF(value); \
21427db96d56Sopenharmony_ci            return -1; \
21437db96d56Sopenharmony_ci        } \
21447db96d56Sopenharmony_ci        Py_DECREF(value); \
21457db96d56Sopenharmony_ci    } while (0)
21467db96d56Sopenharmony_ci
21477db96d56Sopenharmony_cistatic int winapi_exec(PyObject *m)
21487db96d56Sopenharmony_ci{
21497db96d56Sopenharmony_ci    WinApiState *st = winapi_get_state(m);
21507db96d56Sopenharmony_ci
21517db96d56Sopenharmony_ci    st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(m, &winapi_overlapped_type_spec, NULL);
21527db96d56Sopenharmony_ci    if (st->overlapped_type == NULL) {
21537db96d56Sopenharmony_ci        return -1;
21547db96d56Sopenharmony_ci    }
21557db96d56Sopenharmony_ci
21567db96d56Sopenharmony_ci    if (PyModule_AddType(m, st->overlapped_type) < 0) {
21577db96d56Sopenharmony_ci        return -1;
21587db96d56Sopenharmony_ci    }
21597db96d56Sopenharmony_ci
21607db96d56Sopenharmony_ci    PyObject *d = PyModule_GetDict(m);
21617db96d56Sopenharmony_ci
21627db96d56Sopenharmony_ci    /* constants */
21637db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE);
21647db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, CREATE_NEW_PROCESS_GROUP);
21657db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, DUPLICATE_SAME_ACCESS);
21667db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, DUPLICATE_CLOSE_SOURCE);
21677db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
21687db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE);
21697db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
21707db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA);
21717db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
21727db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES);
21737db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA);
21747db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
21757db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_NO_DATA);
21767db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES);
21777db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED);
21787db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
21797db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
21807db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
21817db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_FLAG_FIRST_PIPE_INSTANCE);
21827db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED);
21837db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_READ);
21847db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_WRITE);
21857db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_MAP_ALL_ACCESS);
21867db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_MAP_COPY);
21877db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_MAP_EXECUTE);
21887db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_MAP_READ);
21897db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_MAP_WRITE);
21907db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, GENERIC_READ);
21917db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, GENERIC_WRITE);
21927db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, INFINITE);
21937db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE);
21947db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, MEM_COMMIT);
21957db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, MEM_FREE);
21967db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, MEM_IMAGE);
21977db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, MEM_MAPPED);
21987db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, MEM_PRIVATE);
21997db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, MEM_RESERVE);
22007db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
22017db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, OPEN_EXISTING);
22027db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE);
22037db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READ);
22047db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READWRITE);
22057db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_WRITECOPY);
22067db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_GUARD);
22077db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_NOACCESS);
22087db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_NOCACHE);
22097db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_READONLY);
22107db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_READWRITE);
22117db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOMBINE);
22127db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOPY);
22137db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
22147db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
22157db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
22167db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
22177db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
22187db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PIPE_WAIT);
22197db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
22207db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SYNCHRONIZE);
22217db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, PROCESS_DUP_HANDLE);
22227db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SEC_COMMIT);
22237db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SEC_IMAGE);
22247db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SEC_LARGE_PAGES);
22257db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SEC_NOCACHE);
22267db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SEC_RESERVE);
22277db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SEC_WRITECOMBINE);
22287db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, STARTF_USESHOWWINDOW);
22297db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, STARTF_USESTDHANDLES);
22307db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, STD_INPUT_HANDLE);
22317db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, STD_OUTPUT_HANDLE);
22327db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, STD_ERROR_HANDLE);
22337db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, STILL_ACTIVE);
22347db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, SW_HIDE);
22357db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, WAIT_OBJECT_0);
22367db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, WAIT_ABANDONED_0);
22377db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, WAIT_TIMEOUT);
22387db96d56Sopenharmony_ci
22397db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, ABOVE_NORMAL_PRIORITY_CLASS);
22407db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, BELOW_NORMAL_PRIORITY_CLASS);
22417db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, HIGH_PRIORITY_CLASS);
22427db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, IDLE_PRIORITY_CLASS);
22437db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, NORMAL_PRIORITY_CLASS);
22447db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, REALTIME_PRIORITY_CLASS);
22457db96d56Sopenharmony_ci
22467db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, CREATE_NO_WINDOW);
22477db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, DETACHED_PROCESS);
22487db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, CREATE_DEFAULT_ERROR_MODE);
22497db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, CREATE_BREAKAWAY_FROM_JOB);
22507db96d56Sopenharmony_ci
22517db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_UNKNOWN);
22527db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_DISK);
22537db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_CHAR);
22547db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_PIPE);
22557db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_REMOTE);
22567db96d56Sopenharmony_ci
22577db96d56Sopenharmony_ci    WINAPI_CONSTANT("u", LOCALE_NAME_INVARIANT);
22587db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LOCALE_NAME_MAX_LENGTH);
22597db96d56Sopenharmony_ci    WINAPI_CONSTANT("u", LOCALE_NAME_SYSTEM_DEFAULT);
22607db96d56Sopenharmony_ci    WINAPI_CONSTANT("u", LOCALE_NAME_USER_DEFAULT);
22617db96d56Sopenharmony_ci
22627db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_FULLWIDTH);
22637db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_HALFWIDTH);
22647db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_HIRAGANA);
22657db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_KATAKANA);
22667db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_LINGUISTIC_CASING);
22677db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_LOWERCASE);
22687db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_SIMPLIFIED_CHINESE);
22697db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_TITLECASE);
22707db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_TRADITIONAL_CHINESE);
22717db96d56Sopenharmony_ci    WINAPI_CONSTANT(F_DWORD, LCMAP_UPPERCASE);
22727db96d56Sopenharmony_ci
22737db96d56Sopenharmony_ci    WINAPI_CONSTANT("i", NULL);
22747db96d56Sopenharmony_ci
22757db96d56Sopenharmony_ci    return 0;
22767db96d56Sopenharmony_ci}
22777db96d56Sopenharmony_ci
22787db96d56Sopenharmony_cistatic PyModuleDef_Slot winapi_slots[] = {
22797db96d56Sopenharmony_ci    {Py_mod_exec, winapi_exec},
22807db96d56Sopenharmony_ci    {0, NULL}
22817db96d56Sopenharmony_ci};
22827db96d56Sopenharmony_ci
22837db96d56Sopenharmony_cistatic int
22847db96d56Sopenharmony_ciwinapi_traverse(PyObject *module, visitproc visit, void *arg)
22857db96d56Sopenharmony_ci{
22867db96d56Sopenharmony_ci    WinApiState *st = winapi_get_state(module);
22877db96d56Sopenharmony_ci    Py_VISIT(st->overlapped_type);
22887db96d56Sopenharmony_ci    return 0;
22897db96d56Sopenharmony_ci}
22907db96d56Sopenharmony_ci
22917db96d56Sopenharmony_cistatic int
22927db96d56Sopenharmony_ciwinapi_clear(PyObject *module)
22937db96d56Sopenharmony_ci{
22947db96d56Sopenharmony_ci    WinApiState *st = winapi_get_state(module);
22957db96d56Sopenharmony_ci    Py_CLEAR(st->overlapped_type);
22967db96d56Sopenharmony_ci    return 0;
22977db96d56Sopenharmony_ci}
22987db96d56Sopenharmony_ci
22997db96d56Sopenharmony_cistatic void
23007db96d56Sopenharmony_ciwinapi_free(void *module)
23017db96d56Sopenharmony_ci{
23027db96d56Sopenharmony_ci    winapi_clear((PyObject *)module);
23037db96d56Sopenharmony_ci}
23047db96d56Sopenharmony_ci
23057db96d56Sopenharmony_cistatic struct PyModuleDef winapi_module = {
23067db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
23077db96d56Sopenharmony_ci    .m_name = "_winapi",
23087db96d56Sopenharmony_ci    .m_size = sizeof(WinApiState),
23097db96d56Sopenharmony_ci    .m_methods = winapi_functions,
23107db96d56Sopenharmony_ci    .m_slots = winapi_slots,
23117db96d56Sopenharmony_ci    .m_traverse = winapi_traverse,
23127db96d56Sopenharmony_ci    .m_clear = winapi_clear,
23137db96d56Sopenharmony_ci    .m_free = winapi_free,
23147db96d56Sopenharmony_ci};
23157db96d56Sopenharmony_ci
23167db96d56Sopenharmony_ciPyMODINIT_FUNC
23177db96d56Sopenharmony_ciPyInit__winapi(void)
23187db96d56Sopenharmony_ci{
23197db96d56Sopenharmony_ci    return PyModuleDef_Init(&winapi_module);
23207db96d56Sopenharmony_ci}
2321