/*
 * Support routines from the Windows API
 *
 * This module was originally created by merging PC/_subprocess.c with
 * Modules/_multiprocessing/win32_functions.c.
 *
 * Copyright (c) 2004 by Fredrik Lundh <fredrik@pythonware.com>
 * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com
 * Copyright (c) 2004 by Peter Astrand <astrand@lysator.liu.se>
 *
 * By obtaining, using, and/or copying this software and/or its
 * associated documentation, you agree that you have read, understood,
 * and will comply with the following terms and conditions:
 *
 * Permission to use, copy, modify, and distribute this software and
 * its associated documentation for any purpose and without fee is
 * hereby granted, provided that the above copyright notice appears in
 * all copies, and that both that copyright notice and this permission
 * notice appear in supporting documentation, and that the name of the
 * authors not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior
 * permission.
 *
 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

/* Licensed to PSF under a Contributor Agreement. */
/* See https://www.python.org/2.4/license for licensing details. */

#include "Python.h"
#include "pycore_moduleobject.h"  // _PyModule_GetState()
#include "structmember.h"         // PyMemberDef


#include "windows.h"
#include <crtdbg.h>
#include "winreparse.h"

#include "pycore_runtime.h"       // _Py_ID

#if defined(MS_WIN32) && !defined(MS_WIN64)
#define HANDLE_TO_PYNUM(handle) \
    PyLong_FromUnsignedLong((unsigned long) handle)
#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLong(obj))
#define F_POINTER "k"
#define T_POINTER T_ULONG
#else
#define HANDLE_TO_PYNUM(handle) \
    PyLong_FromUnsignedLongLong((unsigned long long) handle)
#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLongLong(obj))
#define F_POINTER "K"
#define T_POINTER T_ULONGLONG
#endif

#define F_HANDLE F_POINTER
#define F_DWORD "k"

#define T_HANDLE T_POINTER

/* Grab CancelIoEx dynamically from kernel32 */
static int has_CancelIoEx = -1;
static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED);

static int
check_CancelIoEx()
{
    if (has_CancelIoEx == -1)
    {
        HINSTANCE hKernel32 = GetModuleHandle("KERNEL32");
        * (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32,
                                                      "CancelIoEx");
        has_CancelIoEx = (Py_CancelIoEx != NULL);
    }
    return has_CancelIoEx;
}

typedef struct {
    PyTypeObject *overlapped_type;
} WinApiState;

static inline WinApiState*
winapi_get_state(PyObject *module)
{
    void *state = _PyModule_GetState(module);
    assert(state != NULL);
    return (WinApiState *)state;
}

/*
 * A Python object wrapping an OVERLAPPED structure and other useful data
 * for overlapped I/O
 */

typedef struct {
    PyObject_HEAD
    OVERLAPPED overlapped;
    /* For convenience, we store the file handle too */
    HANDLE handle;
    /* Whether there's I/O in flight */
    int pending;
    /* Whether I/O completed successfully */
    int completed;
    /* Buffer used for reading (optional) */
    PyObject *read_buffer;
    /* Buffer used for writing (optional) */
    Py_buffer write_buffer;
} OverlappedObject;

/*
Note: tp_clear (overlapped_clear) is not implemented because it
requires cancelling the IO operation if it's pending and the cancellation is
quite complex and can fail (see: overlapped_dealloc).
*/
static int
overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
{
    Py_VISIT(self->read_buffer);
    Py_VISIT(self->write_buffer.obj);
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static void
overlapped_dealloc(OverlappedObject *self)
{
    DWORD bytes;
    int err = GetLastError();

    PyObject_GC_UnTrack(self);
    if (self->pending) {
        if (check_CancelIoEx() &&
            Py_CancelIoEx(self->handle, &self->overlapped) &&
            GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE))
        {
            /* The operation is no longer pending -- nothing to do. */
        }
        else if (_Py_IsFinalizing())
        {
            /* The operation is still pending -- give a warning.  This
               will probably only happen on Windows XP. */
            PyErr_SetString(PyExc_RuntimeError,
                            "I/O operations still in flight while destroying "
                            "Overlapped object, the process may crash");
            PyErr_WriteUnraisable(NULL);
        }
        else
        {
            /* The operation is still pending, but the process is
               probably about to exit, so we need not worry too much
               about memory leaks.  Leaking self prevents a potential
               crash.  This can happen when a daemon thread is cleaned
               up at exit -- see #19565.  We only expect to get here
               on Windows XP. */
            CloseHandle(self->overlapped.hEvent);
            SetLastError(err);
            return;
        }
    }

    CloseHandle(self->overlapped.hEvent);
    SetLastError(err);
    if (self->write_buffer.obj)
        PyBuffer_Release(&self->write_buffer);
    Py_CLEAR(self->read_buffer);
    PyTypeObject *tp = Py_TYPE(self);
    tp->tp_free(self);
    Py_DECREF(tp);
}

/*[clinic input]
module _winapi
class _winapi.Overlapped "OverlappedObject *" "&OverlappedType"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c13d3f5fd1dabb84]*/

/*[python input]
def create_converter(type_, format_unit):
    name = type_ + '_converter'
    # registered upon creation by CConverter's metaclass
    type(name, (CConverter,), {'type': type_, 'format_unit': format_unit})

# format unit differs between platforms for these
create_converter('HANDLE', '" F_HANDLE "')
create_converter('HMODULE', '" F_HANDLE "')
create_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "')
create_converter('LPCVOID', '" F_POINTER "')

create_converter('BOOL', 'i') # F_BOOL used previously (always 'i')
create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter)
create_converter('LPCTSTR', 's')
create_converter('UINT', 'I') # F_UINT used previously (always 'I')

class LPCWSTR_converter(Py_UNICODE_converter):
    type = 'LPCWSTR'

class HANDLE_return_converter(CReturnConverter):
    type = 'HANDLE'

    def render(self, function, data):
        self.declare(data)
        self.err_occurred_if("_return_value == INVALID_HANDLE_VALUE", data)
        data.return_conversion.append(
            'if (_return_value == NULL) {\n    Py_RETURN_NONE;\n}\n')
        data.return_conversion.append(
            'return_value = HANDLE_TO_PYNUM(_return_value);\n')

class DWORD_return_converter(CReturnConverter):
    type = 'DWORD'

    def render(self, function, data):
        self.declare(data)
        self.err_occurred_if("_return_value == PY_DWORD_MAX", data)
        data.return_conversion.append(
            'return_value = Py_BuildValue("k", _return_value);\n')

class LPVOID_return_converter(CReturnConverter):
    type = 'LPVOID'

    def render(self, function, data):
        self.declare(data)
        self.err_occurred_if("_return_value == NULL", data)
        data.return_conversion.append(
            'return_value = HANDLE_TO_PYNUM(_return_value);\n')
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=011ee0c3a2244bfe]*/

#include "clinic/_winapi.c.h"

/*[clinic input]
_winapi.Overlapped.GetOverlappedResult

    wait: bool
    /
[clinic start generated code]*/

static PyObject *
_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait)
/*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/
{
    BOOL res;
    DWORD transferred = 0;
    DWORD err;

    Py_BEGIN_ALLOW_THREADS
    res = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
                              wait != 0);
    Py_END_ALLOW_THREADS

    err = res ? ERROR_SUCCESS : GetLastError();
    switch (err) {
        case ERROR_SUCCESS:
        case ERROR_MORE_DATA:
        case ERROR_OPERATION_ABORTED:
            self->completed = 1;
            self->pending = 0;
            break;
        case ERROR_IO_INCOMPLETE:
            break;
        default:
            self->pending = 0;
            return PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
    }
    if (self->completed && self->read_buffer != NULL) {
        assert(PyBytes_CheckExact(self->read_buffer));
        if (transferred != PyBytes_GET_SIZE(self->read_buffer) &&
            _PyBytes_Resize(&self->read_buffer, transferred))
            return NULL;
    }
    return Py_BuildValue("II", (unsigned) transferred, (unsigned) err);
}

/*[clinic input]
_winapi.Overlapped.getbuffer
[clinic start generated code]*/

static PyObject *
_winapi_Overlapped_getbuffer_impl(OverlappedObject *self)
/*[clinic end generated code: output=95a3eceefae0f748 input=347fcfd56b4ceabd]*/
{
    PyObject *res;
    if (!self->completed) {
        PyErr_SetString(PyExc_ValueError,
                        "can't get read buffer before GetOverlappedResult() "
                        "signals the operation completed");
        return NULL;
    }
    res = self->read_buffer ? self->read_buffer : Py_None;
    Py_INCREF(res);
    return res;
}

/*[clinic input]
_winapi.Overlapped.cancel
[clinic start generated code]*/

static PyObject *
_winapi_Overlapped_cancel_impl(OverlappedObject *self)
/*[clinic end generated code: output=fcb9ab5df4ebdae5 input=cbf3da142290039f]*/
{
    BOOL res = TRUE;

    if (self->pending) {
        Py_BEGIN_ALLOW_THREADS
        if (check_CancelIoEx())
            res = Py_CancelIoEx(self->handle, &self->overlapped);
        else
            res = CancelIo(self->handle);
        Py_END_ALLOW_THREADS
    }

    /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */
    if (!res && GetLastError() != ERROR_NOT_FOUND)
        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
    self->pending = 0;
    Py_RETURN_NONE;
}

static PyMethodDef overlapped_methods[] = {
    _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF
    _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF
    _WINAPI_OVERLAPPED_CANCEL_METHODDEF
    {NULL}
};

static PyMemberDef overlapped_members[] = {
    {"event", T_HANDLE,
     offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent),
     READONLY, "overlapped event handle"},
    {NULL}
};

static PyType_Slot winapi_overlapped_type_slots[] = {
    {Py_tp_traverse, overlapped_traverse},
    {Py_tp_dealloc, overlapped_dealloc},
    {Py_tp_doc, "OVERLAPPED structure wrapper"},
    {Py_tp_methods, overlapped_methods},
    {Py_tp_members, overlapped_members},
    {0,0}
};

static PyType_Spec winapi_overlapped_type_spec = {
    .name = "_winapi.Overlapped",
    .basicsize = sizeof(OverlappedObject),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
              Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
    .slots = winapi_overlapped_type_slots,
};

static OverlappedObject *
new_overlapped(PyObject *module, HANDLE handle)
{
    WinApiState *st = winapi_get_state(module);
    OverlappedObject *self = PyObject_GC_New(OverlappedObject, st->overlapped_type);
    if (!self)
        return NULL;

    self->handle = handle;
    self->read_buffer = NULL;
    self->pending = 0;
    self->completed = 0;
    memset(&self->overlapped, 0, sizeof(OVERLAPPED));
    memset(&self->write_buffer, 0, sizeof(Py_buffer));
    /* Manual reset, initially non-signalled */
    self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    PyObject_GC_Track(self);
    return self;
}

/* -------------------------------------------------------------------- */
/* windows API functions */

/*[clinic input]
_winapi.CloseHandle

    handle: HANDLE
    /

Close handle.
[clinic start generated code]*/

static PyObject *
_winapi_CloseHandle_impl(PyObject *module, HANDLE handle)
/*[clinic end generated code: output=7ad37345f07bd782 input=7f0e4ac36e0352b8]*/
{
    BOOL success;

    Py_BEGIN_ALLOW_THREADS
    success = CloseHandle(handle);
    Py_END_ALLOW_THREADS

    if (!success)
        return PyErr_SetFromWindowsErr(0);

    Py_RETURN_NONE;
}

/*[clinic input]
_winapi.ConnectNamedPipe

    handle: HANDLE
    overlapped as use_overlapped: bool(accept={int}) = False
[clinic start generated code]*/

static PyObject *
_winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
                              int use_overlapped)
/*[clinic end generated code: output=335a0e7086800671 input=34f937c1c86e5e68]*/
{
    BOOL success;
    OverlappedObject *overlapped = NULL;

    if (use_overlapped) {
        overlapped = new_overlapped(module, handle);
        if (!overlapped)
            return NULL;
    }

    Py_BEGIN_ALLOW_THREADS
    success = ConnectNamedPipe(handle,
                               overlapped ? &overlapped->overlapped : NULL);
    Py_END_ALLOW_THREADS

    if (overlapped) {
        int err = GetLastError();
        /* Overlapped ConnectNamedPipe never returns a success code */
        assert(success == 0);
        if (err == ERROR_IO_PENDING)
            overlapped->pending = 1;
        else if (err == ERROR_PIPE_CONNECTED)
            SetEvent(overlapped->overlapped.hEvent);
        else {
            Py_DECREF(overlapped);
            return PyErr_SetFromWindowsErr(err);
        }
        return (PyObject *) overlapped;
    }
    if (!success)
        return PyErr_SetFromWindowsErr(0);

    Py_RETURN_NONE;
}

/*[clinic input]
_winapi.CreateFile -> HANDLE

    file_name: LPCWSTR
    desired_access: DWORD
    share_mode: DWORD
    security_attributes: LPSECURITY_ATTRIBUTES
    creation_disposition: DWORD
    flags_and_attributes: DWORD
    template_file: HANDLE
    /
[clinic start generated code]*/

static HANDLE
_winapi_CreateFile_impl(PyObject *module, LPCWSTR file_name,
                        DWORD desired_access, DWORD share_mode,
                        LPSECURITY_ATTRIBUTES security_attributes,
                        DWORD creation_disposition,
                        DWORD flags_and_attributes, HANDLE template_file)
/*[clinic end generated code: output=818c811e5e04d550 input=1fa870ed1c2e3d69]*/
{
    HANDLE handle;

    if (PySys_Audit("_winapi.CreateFile", "uIIII",
                    file_name, desired_access, share_mode,
                    creation_disposition, flags_and_attributes) < 0) {
        return INVALID_HANDLE_VALUE;
    }

    Py_BEGIN_ALLOW_THREADS
    handle = CreateFileW(file_name, desired_access,
                         share_mode, security_attributes,
                         creation_disposition,
                         flags_and_attributes, template_file);
    Py_END_ALLOW_THREADS

    if (handle == INVALID_HANDLE_VALUE) {
        PyErr_SetFromWindowsErr(0);
    }

    return handle;
}

/*[clinic input]
_winapi.CreateFileMapping -> HANDLE

    file_handle: HANDLE
    security_attributes: LPSECURITY_ATTRIBUTES
    protect: DWORD
    max_size_high: DWORD
    max_size_low: DWORD
    name: LPCWSTR
    /
[clinic start generated code]*/

static HANDLE
_winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle,
                               LPSECURITY_ATTRIBUTES security_attributes,
                               DWORD protect, DWORD max_size_high,
                               DWORD max_size_low, LPCWSTR name)
/*[clinic end generated code: output=6c0a4d5cf7f6fcc6 input=3dc5cf762a74dee8]*/
{
    HANDLE handle;

    Py_BEGIN_ALLOW_THREADS
    handle = CreateFileMappingW(file_handle, security_attributes,
                                protect, max_size_high, max_size_low,
                                name);
    Py_END_ALLOW_THREADS

    if (handle == NULL) {
        PyObject *temp = PyUnicode_FromWideChar(name, -1);
        PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp);
        Py_XDECREF(temp);
        handle = INVALID_HANDLE_VALUE;
    }

    return handle;
}

/*[clinic input]
_winapi.CreateJunction

    src_path: LPCWSTR
    dst_path: LPCWSTR
    /
[clinic start generated code]*/

static PyObject *
_winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path,
                            LPCWSTR dst_path)
/*[clinic end generated code: output=44b3f5e9bbcc4271 input=963d29b44b9384a7]*/
{
    /* Privilege adjustment */
    HANDLE token = NULL;
    struct {
        TOKEN_PRIVILEGES base;
        /* overallocate by a few array elements */
        LUID_AND_ATTRIBUTES privs[4];
    } tp, previousTp;
    int previousTpSize = 0;

    /* Reparse data buffer */
    const USHORT prefix_len = 4;
    USHORT print_len = 0;
    USHORT rdb_size = 0;
    _Py_PREPARSE_DATA_BUFFER rdb = NULL;

    /* Junction point creation */
    HANDLE junction = NULL;
    DWORD ret = 0;

    if (src_path == NULL || dst_path == NULL)
        return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);

    if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0)
        return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);

    if (PySys_Audit("_winapi.CreateJunction", "uu", src_path, dst_path) < 0) {
        return NULL;
    }

    /* Adjust privileges to allow rewriting directory entry as a
       junction point. */
    if (!OpenProcessToken(GetCurrentProcess(),
                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
        goto cleanup;
    }

    if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.base.Privileges[0].Luid)) {
        goto cleanup;
    }

    tp.base.PrivilegeCount = 1;
    tp.base.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if (!AdjustTokenPrivileges(token, FALSE, &tp.base, sizeof(previousTp),
                               &previousTp.base, &previousTpSize)) {
        goto cleanup;
    }

    if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES)
        goto cleanup;

    /* Store the absolute link target path length in print_len. */
    print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL);
    if (print_len == 0)
        goto cleanup;

    /* NUL terminator should not be part of print_len. */
    --print_len;

    /* REPARSE_DATA_BUFFER usage is heavily under-documented, especially for
       junction points. Here's what I've learned along the way:
       - A junction point has two components: a print name and a substitute
         name. They both describe the link target, but the substitute name is
         the physical target and the print name is shown in directory listings.
       - The print name must be a native name, prefixed with "\??\".
       - Both names are stored after each other in the same buffer (the
         PathBuffer) and both must be NUL-terminated.
       - There are four members defining their respective offset and length
         inside PathBuffer: SubstituteNameOffset, SubstituteNameLength,
         PrintNameOffset and PrintNameLength.
       - The total size we need to allocate for the REPARSE_DATA_BUFFER, thus,
         is the sum of:
         - the fixed header size (REPARSE_DATA_BUFFER_HEADER_SIZE)
         - the size of the MountPointReparseBuffer member without the PathBuffer
         - the size of the prefix ("\??\") in bytes
         - the size of the print name in bytes
         - the size of the substitute name in bytes
         - the size of two NUL terminators in bytes */
    rdb_size = _Py_REPARSE_DATA_BUFFER_HEADER_SIZE +
        sizeof(rdb->MountPointReparseBuffer) -
        sizeof(rdb->MountPointReparseBuffer.PathBuffer) +
        /* Two +1's for NUL terminators. */
        (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR);
    rdb = (_Py_PREPARSE_DATA_BUFFER)PyMem_RawCalloc(1, rdb_size);
    if (rdb == NULL)
        goto cleanup;

    rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
    rdb->ReparseDataLength = rdb_size - _Py_REPARSE_DATA_BUFFER_HEADER_SIZE;
    rdb->MountPointReparseBuffer.SubstituteNameOffset = 0;
    rdb->MountPointReparseBuffer.SubstituteNameLength =
        (prefix_len + print_len) * sizeof(WCHAR);
    rdb->MountPointReparseBuffer.PrintNameOffset =
        rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
    rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR);

    /* Store the full native path of link target at the substitute name
       offset (0). */
    wcscpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\");
    if (GetFullPathNameW(src_path, print_len + 1,
                         rdb->MountPointReparseBuffer.PathBuffer + prefix_len,
                         NULL) == 0)
        goto cleanup;

    /* Copy everything but the native prefix to the print name offset. */
    wcscpy(rdb->MountPointReparseBuffer.PathBuffer +
             prefix_len + print_len + 1,
             rdb->MountPointReparseBuffer.PathBuffer + prefix_len);

    /* Create a directory for the junction point. */
    if (!CreateDirectoryW(dst_path, NULL))
        goto cleanup;

    junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING,
        FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (junction == INVALID_HANDLE_VALUE)
        goto cleanup;

    /* Make the directory entry a junction point. */
    if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size,
                         NULL, 0, &ret, NULL))
        goto cleanup;

cleanup:
    ret = GetLastError();

    if (previousTpSize) {
        AdjustTokenPrivileges(token, FALSE, &previousTp.base, previousTpSize,
                              NULL, NULL);
    }

    if (token != NULL)
        CloseHandle(token);
    if (junction != NULL)
        CloseHandle(junction);
    PyMem_RawFree(rdb);

    if (ret != 0)
        return PyErr_SetFromWindowsErr(ret);

    Py_RETURN_NONE;
}

/*[clinic input]
_winapi.CreateNamedPipe -> HANDLE

    name: LPCTSTR
    open_mode: DWORD
    pipe_mode: DWORD
    max_instances: DWORD
    out_buffer_size: DWORD
    in_buffer_size: DWORD
    default_timeout: DWORD
    security_attributes: LPSECURITY_ATTRIBUTES
    /
[clinic start generated code]*/

static HANDLE
_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode,
                             DWORD pipe_mode, DWORD max_instances,
                             DWORD out_buffer_size, DWORD in_buffer_size,
                             DWORD default_timeout,
                             LPSECURITY_ATTRIBUTES security_attributes)
/*[clinic end generated code: output=80f8c07346a94fbc input=5a73530b84d8bc37]*/
{
    HANDLE handle;

    if (PySys_Audit("_winapi.CreateNamedPipe", "sII",
                    name, open_mode, pipe_mode) < 0) {
        return INVALID_HANDLE_VALUE;
    }

    Py_BEGIN_ALLOW_THREADS
    handle = CreateNamedPipe(name, open_mode, pipe_mode,
                             max_instances, out_buffer_size,
                             in_buffer_size, default_timeout,
                             security_attributes);
    Py_END_ALLOW_THREADS

    if (handle == INVALID_HANDLE_VALUE)
        PyErr_SetFromWindowsErr(0);

    return handle;
}

/*[clinic input]
_winapi.CreatePipe

    pipe_attrs: object
        Ignored internally, can be None.
    size: DWORD
    /

Create an anonymous pipe.

Returns a 2-tuple of handles, to the read and write ends of the pipe.
[clinic start generated code]*/

static PyObject *
_winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size)
/*[clinic end generated code: output=1c4411d8699f0925 input=c4f2cfa56ef68d90]*/
{
    HANDLE read_pipe;
    HANDLE write_pipe;
    BOOL result;

    if (PySys_Audit("_winapi.CreatePipe", NULL) < 0) {
        return NULL;
    }

    Py_BEGIN_ALLOW_THREADS
    result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
    Py_END_ALLOW_THREADS

    if (! result)
        return PyErr_SetFromWindowsErr(GetLastError());

    return Py_BuildValue(
        "NN", HANDLE_TO_PYNUM(read_pipe), HANDLE_TO_PYNUM(write_pipe));
}

/* helpers for createprocess */

static unsigned long
getulong(PyObject* obj, const char* name)
{
    PyObject* value;
    unsigned long ret;

    value = PyObject_GetAttrString(obj, name);
    if (! value) {
        PyErr_Clear(); /* FIXME: propagate error? */
        return 0;
    }
    ret = PyLong_AsUnsignedLong(value);
    Py_DECREF(value);
    return ret;
}

static HANDLE
gethandle(PyObject* obj, const char* name)
{
    PyObject* value;
    HANDLE ret;

    value = PyObject_GetAttrString(obj, name);
    if (! value) {
        PyErr_Clear(); /* FIXME: propagate error? */
        return NULL;
    }
    if (value == Py_None)
        ret = NULL;
    else
        ret = PYNUM_TO_HANDLE(value);
    Py_DECREF(value);
    return ret;
}

static PyObject *
sortenvironmentkey(PyObject *module, PyObject *item)
{
    PyObject *result = NULL;
    PyObject *locale = PyUnicode_FromWideChar(LOCALE_NAME_INVARIANT, -1);
    if (locale) {
        result = _winapi_LCMapStringEx_impl(NULL, locale, LCMAP_UPPERCASE, item);
        Py_DECREF(locale);
    }
    return result;
}

static PyMethodDef sortenvironmentkey_def = {
    "sortenvironmentkey", _PyCFunction_CAST(sortenvironmentkey), METH_O, "",
};

static int
sort_environment_keys(PyObject *keys)
{
    PyObject *keyfunc = PyCFunction_New(&sortenvironmentkey_def, NULL);
    if (keyfunc == NULL) {
        return -1;
    }
    PyObject *kwnames = Py_BuildValue("(s)", "key");
    if (kwnames == NULL) {
        Py_DECREF(keyfunc);
        return -1;
    }
    PyObject *args[] = { keys, keyfunc };
    PyObject *ret = PyObject_VectorcallMethod(&_Py_ID(sort), args, 1, kwnames);
    Py_DECREF(keyfunc);
    Py_DECREF(kwnames);
    if (ret == NULL) {
        return -1;
    }
    Py_DECREF(ret);

    return 0;
}

static int
compare_string_ordinal(PyObject *str1, PyObject *str2, int *result)
{
    wchar_t *s1 = PyUnicode_AsWideCharString(str1, NULL);
    if (s1 == NULL) {
        return -1;
    }
    wchar_t *s2 = PyUnicode_AsWideCharString(str2, NULL);
    if (s2 == NULL) {
        PyMem_Free(s1);
        return -1;
    }
    *result = CompareStringOrdinal(s1, -1, s2, -1, TRUE);
    PyMem_Free(s1);
    PyMem_Free(s2);
    return 0;
}

static PyObject *
dedup_environment_keys(PyObject *keys)
{
    PyObject *result = PyList_New(0);
    if (result == NULL) {
        return NULL;
    }

    // Iterate over the pre-ordered keys, check whether the current key is equal
    // to the next key (ignoring case), if different, insert the current value
    // into the result list. If they are equal, do nothing because we always
    // want to keep the last inserted one.
    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(keys); i++) {
        PyObject *key = PyList_GET_ITEM(keys, i);

        // The last key will always be kept.
        if (i + 1 == PyList_GET_SIZE(keys)) {
            if (PyList_Append(result, key) < 0) {
                Py_DECREF(result);
                return NULL;
            }
            continue;
        }

        PyObject *next_key = PyList_GET_ITEM(keys, i + 1);
        int compare_result;
        if (compare_string_ordinal(key, next_key, &compare_result) < 0) {
            Py_DECREF(result);
            return NULL;
        }
        if (compare_result == CSTR_EQUAL) {
            continue;
        }
        if (PyList_Append(result, key) < 0) {
            Py_DECREF(result);
            return NULL;
        }
    }

    return result;
}

static PyObject *
normalize_environment(PyObject *environment)
{
    PyObject *keys = PyMapping_Keys(environment);
    if (keys == NULL) {
        return NULL;
    }

    if (sort_environment_keys(keys) < 0) {
        Py_DECREF(keys);
        return NULL;
    }

    PyObject *normalized_keys = dedup_environment_keys(keys);
    Py_DECREF(keys);
    if (normalized_keys == NULL) {
        return NULL;
    }

    PyObject *result = PyDict_New();
    if (result == NULL) {
        Py_DECREF(normalized_keys);
        return NULL;
    }

    for (int i = 0; i < PyList_GET_SIZE(normalized_keys); i++) {
        PyObject *key = PyList_GET_ITEM(normalized_keys, i);
        PyObject *value = PyObject_GetItem(environment, key);
        if (value == NULL) {
            Py_DECREF(normalized_keys);
            Py_DECREF(result);
            return NULL;
        }

        int ret = PyObject_SetItem(result, key, value);
        Py_DECREF(value);
        if (ret < 0) {
            Py_DECREF(normalized_keys);
            Py_DECREF(result);
            return NULL;
        }
    }

    Py_DECREF(normalized_keys);

    return result;
}

static wchar_t *
getenvironment(PyObject* environment)
{
    Py_ssize_t i, envsize, totalsize;
    wchar_t *buffer = NULL, *p, *end;
    PyObject *normalized_environment = NULL;
    PyObject *keys = NULL;
    PyObject *values = NULL;

    /* convert environment dictionary to windows environment string */
    if (! PyMapping_Check(environment)) {
        PyErr_SetString(
            PyExc_TypeError, "environment must be dictionary or None");
        return NULL;
    }

    normalized_environment = normalize_environment(environment);
    if (normalize_environment == NULL) {
        return NULL;
    }

    keys = PyMapping_Keys(normalized_environment);
    if (!keys) {
        goto error;
    }
    values = PyMapping_Values(normalized_environment);
    if (!values) {
        goto error;
    }

    envsize = PyList_GET_SIZE(keys);

    if (envsize == 0) {
        // A environment block must be terminated by two null characters --
        // one for the last string and one for the block.
        buffer = PyMem_Calloc(2, sizeof(wchar_t));
        if (!buffer) {
            PyErr_NoMemory();
        }
        goto cleanup;
    }

    if (PyList_GET_SIZE(values) != envsize) {
        PyErr_SetString(PyExc_RuntimeError,
            "environment changed size during iteration");
        goto error;
    }

    totalsize = 1; /* trailing null character */
    for (i = 0; i < envsize; i++) {
        PyObject* key = PyList_GET_ITEM(keys, i);
        PyObject* value = PyList_GET_ITEM(values, i);
        Py_ssize_t size;

        if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) {
            PyErr_SetString(PyExc_TypeError,
                "environment can only contain strings");
            goto error;
        }
        if (PyUnicode_FindChar(key, '\0', 0, PyUnicode_GET_LENGTH(key), 1) != -1 ||
            PyUnicode_FindChar(value, '\0', 0, PyUnicode_GET_LENGTH(value), 1) != -1)
        {
            PyErr_SetString(PyExc_ValueError, "embedded null character");
            goto error;
        }
        /* Search from index 1 because on Windows starting '=' is allowed for
           defining hidden environment variables. */
        if (PyUnicode_GET_LENGTH(key) == 0 ||
            PyUnicode_FindChar(key, '=', 1, PyUnicode_GET_LENGTH(key), 1) != -1)
        {
            PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
            goto error;
        }

        size = PyUnicode_AsWideChar(key, NULL, 0);
        assert(size > 1);
        if (totalsize > PY_SSIZE_T_MAX - size) {
            PyErr_SetString(PyExc_OverflowError, "environment too long");
            goto error;
        }
        totalsize += size;    /* including '=' */

        size = PyUnicode_AsWideChar(value, NULL, 0);
        assert(size > 0);
        if (totalsize > PY_SSIZE_T_MAX - size) {
            PyErr_SetString(PyExc_OverflowError, "environment too long");
            goto error;
        }
        totalsize += size;  /* including trailing '\0' */
    }

    buffer = PyMem_NEW(wchar_t, totalsize);
    if (! buffer) {
        PyErr_NoMemory();
        goto error;
    }
    p = buffer;
    end = buffer + totalsize;

    for (i = 0; i < envsize; i++) {
        PyObject* key = PyList_GET_ITEM(keys, i);
        PyObject* value = PyList_GET_ITEM(values, i);
        Py_ssize_t size = PyUnicode_AsWideChar(key, p, end - p);
        assert(1 <= size && size < end - p);
        p += size;
        *p++ = L'=';
        size = PyUnicode_AsWideChar(value, p, end - p);
        assert(0 <= size && size < end - p);
        p += size + 1;
    }

    /* add trailing null character */
    *p++ = L'\0';
    assert(p == end);

cleanup:
error:
    Py_XDECREF(normalized_environment);
    Py_XDECREF(keys);
    Py_XDECREF(values);
    return buffer;
}

static LPHANDLE
gethandlelist(PyObject *mapping, const char *name, Py_ssize_t *size)
{
    LPHANDLE ret = NULL;
    PyObject *value_fast = NULL;
    PyObject *value;
    Py_ssize_t i;

    value = PyMapping_GetItemString(mapping, name);
    if (!value) {
        PyErr_Clear();
        return NULL;
    }

    if (value == Py_None) {
        goto cleanup;
    }

    value_fast = PySequence_Fast(value, "handle_list must be a sequence or None");
    if (value_fast == NULL)
        goto cleanup;

    *size = PySequence_Fast_GET_SIZE(value_fast) * sizeof(HANDLE);

    /* Passing an empty array causes CreateProcess to fail so just don't set it */
    if (*size == 0) {
        goto cleanup;
    }

    ret = PyMem_Malloc(*size);
    if (ret == NULL)
        goto cleanup;

    for (i = 0; i < PySequence_Fast_GET_SIZE(value_fast); i++) {
        ret[i] = PYNUM_TO_HANDLE(PySequence_Fast_GET_ITEM(value_fast, i));
        if (ret[i] == (HANDLE)-1 && PyErr_Occurred()) {
            PyMem_Free(ret);
            ret = NULL;
            goto cleanup;
        }
    }

cleanup:
    Py_DECREF(value);
    Py_XDECREF(value_fast);
    return ret;
}

typedef struct {
    LPPROC_THREAD_ATTRIBUTE_LIST attribute_list;
    LPHANDLE handle_list;
} AttributeList;

static void
freeattributelist(AttributeList *attribute_list)
{
    if (attribute_list->attribute_list != NULL) {
        DeleteProcThreadAttributeList(attribute_list->attribute_list);
        PyMem_Free(attribute_list->attribute_list);
    }

    PyMem_Free(attribute_list->handle_list);

    memset(attribute_list, 0, sizeof(*attribute_list));
}

static int
getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list)
{
    int ret = 0;
    DWORD err;
    BOOL result;
    PyObject *value;
    Py_ssize_t handle_list_size;
    DWORD attribute_count = 0;
    SIZE_T attribute_list_size = 0;

    value = PyObject_GetAttrString(obj, name);
    if (!value) {
        PyErr_Clear(); /* FIXME: propagate error? */
        return 0;
    }

    if (value == Py_None) {
        ret = 0;
        goto cleanup;
    }

    if (!PyMapping_Check(value)) {
        ret = -1;
        PyErr_Format(PyExc_TypeError, "%s must be a mapping or None", name);
        goto cleanup;
    }

    attribute_list->handle_list = gethandlelist(value, "handle_list", &handle_list_size);
    if (attribute_list->handle_list == NULL && PyErr_Occurred()) {
        ret = -1;
        goto cleanup;
    }

    if (attribute_list->handle_list != NULL)
        ++attribute_count;

    /* Get how many bytes we need for the attribute list */
    result = InitializeProcThreadAttributeList(NULL, attribute_count, 0, &attribute_list_size);
    if (result || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        ret = -1;
        PyErr_SetFromWindowsErr(GetLastError());
        goto cleanup;
    }

    attribute_list->attribute_list = PyMem_Malloc(attribute_list_size);
    if (attribute_list->attribute_list == NULL) {
        ret = -1;
        goto cleanup;
    }

    result = InitializeProcThreadAttributeList(
        attribute_list->attribute_list,
        attribute_count,
        0,
        &attribute_list_size);
    if (!result) {
        err = GetLastError();

        /* So that we won't call DeleteProcThreadAttributeList */
        PyMem_Free(attribute_list->attribute_list);
        attribute_list->attribute_list = NULL;

        ret = -1;
        PyErr_SetFromWindowsErr(err);
        goto cleanup;
    }

    if (attribute_list->handle_list != NULL) {
        result = UpdateProcThreadAttribute(
            attribute_list->attribute_list,
            0,
            PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
            attribute_list->handle_list,
            handle_list_size,
            NULL,
            NULL);
        if (!result) {
            ret = -1;
            PyErr_SetFromWindowsErr(GetLastError());
            goto cleanup;
        }
    }

cleanup:
    Py_DECREF(value);

    if (ret < 0)
        freeattributelist(attribute_list);

    return ret;
}

/*[clinic input]
_winapi.CreateProcess

    application_name: Py_UNICODE(accept={str, NoneType})
    command_line: object
        Can be str or None
    proc_attrs: object
        Ignored internally, can be None.
    thread_attrs: object
        Ignored internally, can be None.
    inherit_handles: BOOL
    creation_flags: DWORD
    env_mapping: object
    current_directory: Py_UNICODE(accept={str, NoneType})
    startup_info: object
    /

Create a new process and its primary thread.

The return value is a tuple of the process handle, thread handle,
process ID, and thread ID.
[clinic start generated code]*/

static PyObject *
_winapi_CreateProcess_impl(PyObject *module,
                           const Py_UNICODE *application_name,
                           PyObject *command_line, PyObject *proc_attrs,
                           PyObject *thread_attrs, BOOL inherit_handles,
                           DWORD creation_flags, PyObject *env_mapping,
                           const Py_UNICODE *current_directory,
                           PyObject *startup_info)
/*[clinic end generated code: output=9b2423a609230132 input=42ac293eaea03fc4]*/
{
    PyObject *ret = NULL;
    BOOL result;
    PROCESS_INFORMATION pi;
    STARTUPINFOEXW si;
    wchar_t *wenvironment = NULL;
    wchar_t *command_line_copy = NULL;
    AttributeList attribute_list = {0};

    if (PySys_Audit("_winapi.CreateProcess", "uuu", application_name,
                    command_line, current_directory) < 0) {
        return NULL;
    }

    PyInterpreterState *interp = PyInterpreterState_Get();
    const PyConfig *config = _PyInterpreterState_GetConfig(interp);
    if (config->_isolated_interpreter) {
        PyErr_SetString(PyExc_RuntimeError,
                        "subprocess not supported for isolated subinterpreters");
        return NULL;
    }

    ZeroMemory(&si, sizeof(si));
    si.StartupInfo.cb = sizeof(si);

    /* note: we only support a small subset of all SI attributes */
    si.StartupInfo.dwFlags = getulong(startup_info, "dwFlags");
    si.StartupInfo.wShowWindow = (WORD)getulong(startup_info, "wShowWindow");
    si.StartupInfo.hStdInput = gethandle(startup_info, "hStdInput");
    si.StartupInfo.hStdOutput = gethandle(startup_info, "hStdOutput");
    si.StartupInfo.hStdError = gethandle(startup_info, "hStdError");
    if (PyErr_Occurred())
        goto cleanup;

    if (env_mapping != Py_None) {
        wenvironment = getenvironment(env_mapping);
        if (wenvironment == NULL) {
            goto cleanup;
        }
    }

    if (getattributelist(startup_info, "lpAttributeList", &attribute_list) < 0)
        goto cleanup;

    si.lpAttributeList = attribute_list.attribute_list;
    if (PyUnicode_Check(command_line)) {
        command_line_copy = PyUnicode_AsWideCharString(command_line, NULL);
        if (command_line_copy == NULL) {
            goto cleanup;
        }
    }
    else if (command_line != Py_None) {
        PyErr_Format(PyExc_TypeError,
                     "CreateProcess() argument 2 must be str or None, not %s",
                     Py_TYPE(command_line)->tp_name);
        goto cleanup;
    }


    Py_BEGIN_ALLOW_THREADS
    result = CreateProcessW(application_name,
                           command_line_copy,
                           NULL,
                           NULL,
                           inherit_handles,
                           creation_flags | EXTENDED_STARTUPINFO_PRESENT |
                           CREATE_UNICODE_ENVIRONMENT,
                           wenvironment,
                           current_directory,
                           (LPSTARTUPINFOW)&si,
                           &pi);
    Py_END_ALLOW_THREADS

    if (!result) {
        PyErr_SetFromWindowsErr(GetLastError());
        goto cleanup;
    }

    ret = Py_BuildValue("NNkk",
                        HANDLE_TO_PYNUM(pi.hProcess),
                        HANDLE_TO_PYNUM(pi.hThread),
                        pi.dwProcessId,
                        pi.dwThreadId);

cleanup:
    PyMem_Free(command_line_copy);
    PyMem_Free(wenvironment);
    freeattributelist(&attribute_list);

    return ret;
}

/*[clinic input]
_winapi.DuplicateHandle -> HANDLE

    source_process_handle: HANDLE
    source_handle: HANDLE
    target_process_handle: HANDLE
    desired_access: DWORD
    inherit_handle: BOOL
    options: DWORD = 0
    /

Return a duplicate handle object.

The duplicate handle refers to the same object as the original
handle. Therefore, any changes to the object are reflected
through both handles.
[clinic start generated code]*/

static HANDLE
_winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle,
                             HANDLE source_handle,
                             HANDLE target_process_handle,
                             DWORD desired_access, BOOL inherit_handle,
                             DWORD options)
/*[clinic end generated code: output=ad9711397b5dcd4e input=b933e3f2356a8c12]*/
{
    HANDLE target_handle;
    BOOL result;

    Py_BEGIN_ALLOW_THREADS
    result = DuplicateHandle(
        source_process_handle,
        source_handle,
        target_process_handle,
        &target_handle,
        desired_access,
        inherit_handle,
        options
    );
    Py_END_ALLOW_THREADS

    if (! result) {
        PyErr_SetFromWindowsErr(GetLastError());
        return INVALID_HANDLE_VALUE;
    }

    return target_handle;
}

/*[clinic input]
_winapi.ExitProcess

    ExitCode: UINT
    /

[clinic start generated code]*/

static PyObject *
_winapi_ExitProcess_impl(PyObject *module, UINT ExitCode)
/*[clinic end generated code: output=a387deb651175301 input=4f05466a9406c558]*/
{
    #if defined(Py_DEBUG)
        SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|
                     SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
        _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
    #endif

    ExitProcess(ExitCode);

    return NULL;
}

/*[clinic input]
_winapi.GetCurrentProcess -> HANDLE

Return a handle object for the current process.
[clinic start generated code]*/

static HANDLE
_winapi_GetCurrentProcess_impl(PyObject *module)
/*[clinic end generated code: output=ddeb4dd2ffadf344 input=b213403fd4b96b41]*/
{
    return GetCurrentProcess();
}

/*[clinic input]
_winapi.GetExitCodeProcess -> DWORD

    process: HANDLE
    /

Return the termination status of the specified process.
[clinic start generated code]*/

static DWORD
_winapi_GetExitCodeProcess_impl(PyObject *module, HANDLE process)
/*[clinic end generated code: output=b4620bdf2bccf36b input=61b6bfc7dc2ee374]*/
{
    DWORD exit_code;
    BOOL result;

    result = GetExitCodeProcess(process, &exit_code);

    if (! result) {
        PyErr_SetFromWindowsErr(GetLastError());
        exit_code = PY_DWORD_MAX;
    }

    return exit_code;
}

/*[clinic input]
_winapi.GetLastError -> DWORD
[clinic start generated code]*/

static DWORD
_winapi_GetLastError_impl(PyObject *module)
/*[clinic end generated code: output=8585b827cb1a92c5 input=62d47fb9bce038ba]*/
{
    return GetLastError();
}

/*[clinic input]
_winapi.GetModuleFileName

    module_handle: HMODULE
    /

Return the fully-qualified path for the file that contains module.

The module must have been loaded by the current process.

The module parameter should be a handle to the loaded module
whose path is being requested. If this parameter is 0,
GetModuleFileName retrieves the path of the executable file
of the current process.
[clinic start generated code]*/

static PyObject *
_winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle)
/*[clinic end generated code: output=85b4b728c5160306 input=6d66ff7deca5d11f]*/
{
    BOOL result;
    WCHAR filename[MAX_PATH];

    Py_BEGIN_ALLOW_THREADS
    result = GetModuleFileNameW(module_handle, filename, MAX_PATH);
    filename[MAX_PATH-1] = '\0';
    Py_END_ALLOW_THREADS

    if (! result)
        return PyErr_SetFromWindowsErr(GetLastError());

    return PyUnicode_FromWideChar(filename, wcslen(filename));
}

/*[clinic input]
_winapi.GetStdHandle -> HANDLE

    std_handle: DWORD
        One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE.
    /

Return a handle to the specified standard device.

The integer associated with the handle object is returned.
[clinic start generated code]*/

static HANDLE
_winapi_GetStdHandle_impl(PyObject *module, DWORD std_handle)
/*[clinic end generated code: output=0e613001e73ab614 input=07016b06a2fc8826]*/
{
    HANDLE handle;

    Py_BEGIN_ALLOW_THREADS
    handle = GetStdHandle(std_handle);
    Py_END_ALLOW_THREADS

    if (handle == INVALID_HANDLE_VALUE)
        PyErr_SetFromWindowsErr(GetLastError());

    return handle;
}

/*[clinic input]
_winapi.GetVersion -> long

Return the version number of the current operating system.
[clinic start generated code]*/

static long
_winapi_GetVersion_impl(PyObject *module)
/*[clinic end generated code: output=e41f0db5a3b82682 input=e21dff8d0baeded2]*/
/* Disable deprecation warnings about GetVersionEx as the result is
   being passed straight through to the caller, who is responsible for
   using it correctly. */
#pragma warning(push)
#pragma warning(disable:4996)

{
    return GetVersion();
}

#pragma warning(pop)

/*[clinic input]
_winapi.MapViewOfFile -> LPVOID

    file_map: HANDLE
    desired_access: DWORD
    file_offset_high: DWORD
    file_offset_low: DWORD
    number_bytes: size_t
    /
[clinic start generated code]*/

static LPVOID
_winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map,
                           DWORD desired_access, DWORD file_offset_high,
                           DWORD file_offset_low, size_t number_bytes)
/*[clinic end generated code: output=f23b1ee4823663e3 input=177471073be1a103]*/
{
    LPVOID address;

    Py_BEGIN_ALLOW_THREADS
    address = MapViewOfFile(file_map, desired_access, file_offset_high,
                            file_offset_low, number_bytes);
    Py_END_ALLOW_THREADS

    if (address == NULL)
        PyErr_SetFromWindowsErr(0);

    return address;
}

/*[clinic input]
_winapi.UnmapViewOfFile

    address: LPCVOID
    /
[clinic start generated code]*/

static PyObject *
_winapi_UnmapViewOfFile_impl(PyObject *module, LPCVOID address)
/*[clinic end generated code: output=4f7e18ac75d19744 input=8c4b6119ad9288a3]*/
{
    BOOL success;

    Py_BEGIN_ALLOW_THREADS
    success = UnmapViewOfFile(address);
    Py_END_ALLOW_THREADS

    if (!success) {
        return PyErr_SetFromWindowsErr(0);
    }

    Py_RETURN_NONE;
}

/*[clinic input]
_winapi.OpenFileMapping -> HANDLE

    desired_access: DWORD
    inherit_handle: BOOL
    name: LPCWSTR
    /
[clinic start generated code]*/

static HANDLE
_winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access,
                             BOOL inherit_handle, LPCWSTR name)
/*[clinic end generated code: output=08cc44def1cb11f1 input=131f2a405359de7f]*/
{
    HANDLE handle;

    Py_BEGIN_ALLOW_THREADS
    handle = OpenFileMappingW(desired_access, inherit_handle, name);
    Py_END_ALLOW_THREADS

    if (handle == NULL) {
        PyObject *temp = PyUnicode_FromWideChar(name, -1);
        PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp);
        Py_XDECREF(temp);
        handle = INVALID_HANDLE_VALUE;
    }

    return handle;
}

/*[clinic input]
_winapi.OpenProcess -> HANDLE

    desired_access: DWORD
    inherit_handle: BOOL
    process_id: DWORD
    /
[clinic start generated code]*/

static HANDLE
_winapi_OpenProcess_impl(PyObject *module, DWORD desired_access,
                         BOOL inherit_handle, DWORD process_id)
/*[clinic end generated code: output=b42b6b81ea5a0fc3 input=ec98c4cf4ea2ec36]*/
{
    HANDLE handle;

    if (PySys_Audit("_winapi.OpenProcess", "II",
                    process_id, desired_access) < 0) {
        return INVALID_HANDLE_VALUE;
    }

    Py_BEGIN_ALLOW_THREADS
    handle = OpenProcess(desired_access, inherit_handle, process_id);
    Py_END_ALLOW_THREADS
    if (handle == NULL) {
        PyErr_SetFromWindowsErr(GetLastError());
        handle = INVALID_HANDLE_VALUE;
    }

    return handle;
}

/*[clinic input]
_winapi.PeekNamedPipe

    handle: HANDLE
    size: int = 0
    /
[clinic start generated code]*/

static PyObject *
_winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size)
/*[clinic end generated code: output=d0c3e29e49d323dd input=c7aa53bfbce69d70]*/
{
    PyObject *buf = NULL;
    DWORD nread, navail, nleft;
    BOOL ret;

    if (size < 0) {
        PyErr_SetString(PyExc_ValueError, "negative size");
        return NULL;
    }

    if (size) {
        buf = PyBytes_FromStringAndSize(NULL, size);
        if (!buf)
            return NULL;
        Py_BEGIN_ALLOW_THREADS
        ret = PeekNamedPipe(handle, PyBytes_AS_STRING(buf), size, &nread,
                            &navail, &nleft);
        Py_END_ALLOW_THREADS
        if (!ret) {
            Py_DECREF(buf);
            return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
        }
        if (_PyBytes_Resize(&buf, nread))
            return NULL;
        return Py_BuildValue("NII", buf, navail, nleft);
    }
    else {
        Py_BEGIN_ALLOW_THREADS
        ret = PeekNamedPipe(handle, NULL, 0, NULL, &navail, &nleft);
        Py_END_ALLOW_THREADS
        if (!ret) {
            return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
        }
        return Py_BuildValue("II", navail, nleft);
    }
}

/*[clinic input]
_winapi.LCMapStringEx

    locale: unicode
    flags: DWORD
    src: unicode

[clinic start generated code]*/

static PyObject *
_winapi_LCMapStringEx_impl(PyObject *module, PyObject *locale, DWORD flags,
                           PyObject *src)
/*[clinic end generated code: output=8ea4c9d85a4a1f23 input=2fa6ebc92591731b]*/
{
    if (flags & (LCMAP_SORTHANDLE | LCMAP_HASH | LCMAP_BYTEREV |
                 LCMAP_SORTKEY)) {
        return PyErr_Format(PyExc_ValueError, "unsupported flags");
    }

    wchar_t *locale_ = PyUnicode_AsWideCharString(locale, NULL);
    if (!locale_) {
        return NULL;
    }
    Py_ssize_t src_size;
    wchar_t *src_ = PyUnicode_AsWideCharString(src, &src_size);
    if (!src_) {
        PyMem_Free(locale_);
        return NULL;
    }
    if (src_size > INT_MAX) {
        PyMem_Free(locale_);
        PyMem_Free(src_);
        PyErr_SetString(PyExc_OverflowError, "input string is too long");
        return NULL;
    }

    int dest_size = LCMapStringEx(locale_, flags, src_, (int)src_size, NULL, 0,
                                  NULL, NULL, 0);
    if (dest_size <= 0) {
        DWORD error = GetLastError();
        PyMem_Free(locale_);
        PyMem_Free(src_);
        return PyErr_SetFromWindowsErr(error);
    }

    wchar_t* dest = PyMem_NEW(wchar_t, dest_size);
    if (dest == NULL) {
        PyMem_Free(locale_);
        PyMem_Free(src_);
        return PyErr_NoMemory();
    }

    int nmapped = LCMapStringEx(locale_, flags, src_, (int)src_size, dest, dest_size,
                                NULL, NULL, 0);
    if (nmapped <= 0) {
        DWORD error = GetLastError();
        PyMem_Free(locale_);
        PyMem_Free(src_);
        PyMem_DEL(dest);
        return PyErr_SetFromWindowsErr(error);
    }

    PyMem_Free(locale_);
    PyMem_Free(src_);
    PyObject *ret = PyUnicode_FromWideChar(dest, nmapped);
    PyMem_DEL(dest);

    return ret;
}

/*[clinic input]
_winapi.ReadFile

    handle: HANDLE
    size: DWORD
    overlapped as use_overlapped: bool(accept={int}) = False
[clinic start generated code]*/

static PyObject *
_winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size,
                      int use_overlapped)
/*[clinic end generated code: output=d3d5b44a8201b944 input=08c439d03a11aac5]*/
{
    DWORD nread;
    PyObject *buf;
    BOOL ret;
    DWORD err;
    OverlappedObject *overlapped = NULL;

    buf = PyBytes_FromStringAndSize(NULL, size);
    if (!buf)
        return NULL;
    if (use_overlapped) {
        overlapped = new_overlapped(module, handle);
        if (!overlapped) {
            Py_DECREF(buf);
            return NULL;
        }
        /* Steals reference to buf */
        overlapped->read_buffer = buf;
    }

    Py_BEGIN_ALLOW_THREADS
    ret = ReadFile(handle, PyBytes_AS_STRING(buf), size, &nread,
                   overlapped ? &overlapped->overlapped : NULL);
    Py_END_ALLOW_THREADS

    err = ret ? 0 : GetLastError();

    if (overlapped) {
        if (!ret) {
            if (err == ERROR_IO_PENDING)
                overlapped->pending = 1;
            else if (err != ERROR_MORE_DATA) {
                Py_DECREF(overlapped);
                return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
            }
        }
        return Py_BuildValue("NI", (PyObject *) overlapped, err);
    }

    if (!ret && err != ERROR_MORE_DATA) {
        Py_DECREF(buf);
        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
    }
    if (_PyBytes_Resize(&buf, nread))
        return NULL;
    return Py_BuildValue("NI", buf, err);
}

/*[clinic input]
_winapi.SetNamedPipeHandleState

    named_pipe: HANDLE
    mode: object
    max_collection_count: object
    collect_data_timeout: object
    /
[clinic start generated code]*/

static PyObject *
_winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe,
                                     PyObject *mode,
                                     PyObject *max_collection_count,
                                     PyObject *collect_data_timeout)
/*[clinic end generated code: output=f2129d222cbfa095 input=9142d72163d0faa6]*/
{
    PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout};
    DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
    int i;
    BOOL b;

    for (i = 0 ; i < 3 ; i++) {
        if (oArgs[i] != Py_None) {
            dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
            if (PyErr_Occurred())
                return NULL;
            pArgs[i] = &dwArgs[i];
        }
    }

    Py_BEGIN_ALLOW_THREADS
    b = SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2]);
    Py_END_ALLOW_THREADS

    if (!b)
        return PyErr_SetFromWindowsErr(0);

    Py_RETURN_NONE;
}


/*[clinic input]
_winapi.TerminateProcess

    handle: HANDLE
    exit_code: UINT
    /

Terminate the specified process and all of its threads.
[clinic start generated code]*/

static PyObject *
_winapi_TerminateProcess_impl(PyObject *module, HANDLE handle,
                              UINT exit_code)
/*[clinic end generated code: output=f4e99ac3f0b1f34a input=d6bc0aa1ee3bb4df]*/
{
    BOOL result;

    if (PySys_Audit("_winapi.TerminateProcess", "nI",
                    (Py_ssize_t)handle, exit_code) < 0) {
        return NULL;
    }

    result = TerminateProcess(handle, exit_code);

    if (! result)
        return PyErr_SetFromWindowsErr(GetLastError());

    Py_RETURN_NONE;
}

/*[clinic input]
_winapi.VirtualQuerySize -> size_t

    address: LPCVOID
    /
[clinic start generated code]*/

static size_t
_winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address)
/*[clinic end generated code: output=40c8e0ff5ec964df input=6b784a69755d0bb6]*/
{
    SIZE_T size_of_buf;
    MEMORY_BASIC_INFORMATION mem_basic_info;
    SIZE_T region_size;

    Py_BEGIN_ALLOW_THREADS
    size_of_buf = VirtualQuery(address, &mem_basic_info, sizeof(mem_basic_info));
    Py_END_ALLOW_THREADS

    if (size_of_buf == 0)
        PyErr_SetFromWindowsErr(0);

    region_size = mem_basic_info.RegionSize;
    return region_size;
}

/*[clinic input]
_winapi.WaitNamedPipe

    name: LPCTSTR
    timeout: DWORD
    /
[clinic start generated code]*/

static PyObject *
_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout)
/*[clinic end generated code: output=c2866f4439b1fe38 input=36fc781291b1862c]*/
{
    BOOL success;

    Py_BEGIN_ALLOW_THREADS
    success = WaitNamedPipe(name, timeout);
    Py_END_ALLOW_THREADS

    if (!success)
        return PyErr_SetFromWindowsErr(0);

    Py_RETURN_NONE;
}

/*[clinic input]
_winapi.WaitForMultipleObjects

    handle_seq: object
    wait_flag: BOOL
    milliseconds: DWORD(c_default='INFINITE') = _winapi.INFINITE
    /
[clinic start generated code]*/

static PyObject *
_winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq,
                                    BOOL wait_flag, DWORD milliseconds)
/*[clinic end generated code: output=295e3f00b8e45899 input=36f76ca057cd28a0]*/
{
    DWORD result;
    HANDLE handles[MAXIMUM_WAIT_OBJECTS];
    HANDLE sigint_event = NULL;
    Py_ssize_t nhandles, i;

    if (!PySequence_Check(handle_seq)) {
        PyErr_Format(PyExc_TypeError,
                     "sequence type expected, got '%s'",
                     Py_TYPE(handle_seq)->tp_name);
        return NULL;
    }
    nhandles = PySequence_Length(handle_seq);
    if (nhandles == -1)
        return NULL;
    if (nhandles < 0 || nhandles > MAXIMUM_WAIT_OBJECTS - 1) {
        PyErr_Format(PyExc_ValueError,
                     "need at most %zd handles, got a sequence of length %zd",
                     MAXIMUM_WAIT_OBJECTS - 1, nhandles);
        return NULL;
    }
    for (i = 0; i < nhandles; i++) {
        HANDLE h;
        PyObject *v = PySequence_GetItem(handle_seq, i);
        if (v == NULL)
            return NULL;
        if (!PyArg_Parse(v, F_HANDLE, &h)) {
            Py_DECREF(v);
            return NULL;
        }
        handles[i] = h;
        Py_DECREF(v);
    }
    /* If this is the main thread then make the wait interruptible
       by Ctrl-C unless we are waiting for *all* handles */
    if (!wait_flag && _PyOS_IsMainThread()) {
        sigint_event = _PyOS_SigintEvent();
        assert(sigint_event != NULL);
        handles[nhandles++] = sigint_event;
    }

    Py_BEGIN_ALLOW_THREADS
    if (sigint_event != NULL)
        ResetEvent(sigint_event);
    result = WaitForMultipleObjects((DWORD) nhandles, handles,
                                    wait_flag, milliseconds);
    Py_END_ALLOW_THREADS

    if (result == WAIT_FAILED)
        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
    else if (sigint_event != NULL && result == WAIT_OBJECT_0 + nhandles - 1) {
        errno = EINTR;
        return PyErr_SetFromErrno(PyExc_OSError);
    }

    return PyLong_FromLong((int) result);
}

/*[clinic input]
_winapi.WaitForSingleObject -> long

    handle: HANDLE
    milliseconds: DWORD
    /

Wait for a single object.

Wait until the specified object is in the signaled state or
the time-out interval elapses. The timeout value is specified
in milliseconds.
[clinic start generated code]*/

static long
_winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle,
                                 DWORD milliseconds)
/*[clinic end generated code: output=3c4715d8f1b39859 input=443d1ab076edc7b1]*/
{
    DWORD result;

    Py_BEGIN_ALLOW_THREADS
    result = WaitForSingleObject(handle, milliseconds);
    Py_END_ALLOW_THREADS

    if (result == WAIT_FAILED) {
        PyErr_SetFromWindowsErr(GetLastError());
        return -1;
    }

    return result;
}

/*[clinic input]
_winapi.WriteFile

    handle: HANDLE
    buffer: object
    overlapped as use_overlapped: bool(accept={int}) = False
[clinic start generated code]*/

static PyObject *
_winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer,
                       int use_overlapped)
/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=11eae2a03aa32731]*/
{
    Py_buffer _buf, *buf;
    DWORD len, written;
    BOOL ret;
    DWORD err;
    OverlappedObject *overlapped = NULL;

    if (use_overlapped) {
        overlapped = new_overlapped(module, handle);
        if (!overlapped)
            return NULL;
        buf = &overlapped->write_buffer;
    }
    else
        buf = &_buf;

    if (!PyArg_Parse(buffer, "y*", buf)) {
        Py_XDECREF(overlapped);
        return NULL;
    }

    Py_BEGIN_ALLOW_THREADS
    len = (DWORD)Py_MIN(buf->len, PY_DWORD_MAX);
    ret = WriteFile(handle, buf->buf, len, &written,
                    overlapped ? &overlapped->overlapped : NULL);
    Py_END_ALLOW_THREADS

    err = ret ? 0 : GetLastError();

    if (overlapped) {
        if (!ret) {
            if (err == ERROR_IO_PENDING)
                overlapped->pending = 1;
            else {
                Py_DECREF(overlapped);
                return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
            }
        }
        return Py_BuildValue("NI", (PyObject *) overlapped, err);
    }

    PyBuffer_Release(buf);
    if (!ret)
        return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0);
    return Py_BuildValue("II", written, err);
}

/*[clinic input]
_winapi.GetACP

Get the current Windows ANSI code page identifier.
[clinic start generated code]*/

static PyObject *
_winapi_GetACP_impl(PyObject *module)
/*[clinic end generated code: output=f7ee24bf705dbb88 input=1433c96d03a05229]*/
{
    return PyLong_FromUnsignedLong(GetACP());
}

/*[clinic input]
_winapi.GetFileType -> DWORD

    handle: HANDLE
[clinic start generated code]*/

static DWORD
_winapi_GetFileType_impl(PyObject *module, HANDLE handle)
/*[clinic end generated code: output=92b8466ac76ecc17 input=0058366bc40bbfbf]*/
{
    DWORD result;

    Py_BEGIN_ALLOW_THREADS
    result = GetFileType(handle);
    Py_END_ALLOW_THREADS

    if (result == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR) {
        PyErr_SetFromWindowsErr(0);
        return -1;
    }

    return result;
}

/*[clinic input]
_winapi._mimetypes_read_windows_registry

    on_type_read: object

Optimized function for reading all known MIME types from the registry.

*on_type_read* is a callable taking *type* and *ext* arguments, as for
MimeTypes.add_type.
[clinic start generated code]*/

static PyObject *
_winapi__mimetypes_read_windows_registry_impl(PyObject *module,
                                              PyObject *on_type_read)
/*[clinic end generated code: output=20829f00bebce55b input=cd357896d6501f68]*/
{
#define CCH_EXT 128
#define CB_TYPE 510
    struct {
        wchar_t ext[CCH_EXT];
        wchar_t type[CB_TYPE / sizeof(wchar_t) + 1];
    } entries[64];
    int entry = 0;
    HKEY hkcr = NULL;
    LRESULT err;

    Py_BEGIN_ALLOW_THREADS
    err = RegOpenKeyExW(HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &hkcr);
    for (DWORD i = 0; err == ERROR_SUCCESS || err == ERROR_MORE_DATA; ++i) {
        LPWSTR ext = entries[entry].ext;
        LPWSTR type = entries[entry].type;
        DWORD cchExt = CCH_EXT;
        DWORD cbType = CB_TYPE;
        HKEY subkey;
        DWORD regType;

        err = RegEnumKeyExW(hkcr, i, ext, &cchExt, NULL, NULL, NULL, NULL);
        if (err != ERROR_SUCCESS || (cchExt && ext[0] != L'.')) {
            continue;
        }

        err = RegOpenKeyExW(hkcr, ext, 0, KEY_READ, &subkey);
        if (err == ERROR_FILE_NOT_FOUND) {
            err = ERROR_SUCCESS;
            continue;
        } else if (err != ERROR_SUCCESS) {
            continue;
        }

        err = RegQueryValueExW(subkey, L"Content Type", NULL,
                              &regType, (LPBYTE)type, &cbType);
        RegCloseKey(subkey);
        if (err == ERROR_FILE_NOT_FOUND) {
            err = ERROR_SUCCESS;
            continue;
        } else if (err != ERROR_SUCCESS) {
            continue;
        } else if (regType != REG_SZ || !cbType) {
            continue;
        }
        type[cbType / sizeof(wchar_t)] = L'\0';

        entry += 1;

        /* Flush our cached entries if we are full */
        if (entry == sizeof(entries) / sizeof(entries[0])) {
            Py_BLOCK_THREADS
            for (int j = 0; j < entry; ++j) {
                PyObject *r = PyObject_CallFunction(
                    on_type_read, "uu", entries[j].type, entries[j].ext
                );
                if (!r) {
                    /* We blocked threads, so safe to return from here */
                    RegCloseKey(hkcr);
                    return NULL;
                }
                Py_DECREF(r);
            }
            Py_UNBLOCK_THREADS
            entry = 0;
        }
    }
    if (hkcr) {
        RegCloseKey(hkcr);
    }
    Py_END_ALLOW_THREADS

    if (err != ERROR_SUCCESS && err != ERROR_NO_MORE_ITEMS) {
        PyErr_SetFromWindowsErr((int)err);
        return NULL;
    }

    for (int j = 0; j < entry; ++j) {
        PyObject *r = PyObject_CallFunction(
            on_type_read, "uu", entries[j].type, entries[j].ext
        );
        if (!r) {
            return NULL;
        }
        Py_DECREF(r);
    }

    Py_RETURN_NONE;
#undef CCH_EXT
#undef CB_TYPE
}


static PyMethodDef winapi_functions[] = {
    _WINAPI_CLOSEHANDLE_METHODDEF
    _WINAPI_CONNECTNAMEDPIPE_METHODDEF
    _WINAPI_CREATEFILE_METHODDEF
    _WINAPI_CREATEFILEMAPPING_METHODDEF
    _WINAPI_CREATENAMEDPIPE_METHODDEF
    _WINAPI_CREATEPIPE_METHODDEF
    _WINAPI_CREATEPROCESS_METHODDEF
    _WINAPI_CREATEJUNCTION_METHODDEF
    _WINAPI_DUPLICATEHANDLE_METHODDEF
    _WINAPI_EXITPROCESS_METHODDEF
    _WINAPI_GETCURRENTPROCESS_METHODDEF
    _WINAPI_GETEXITCODEPROCESS_METHODDEF
    _WINAPI_GETLASTERROR_METHODDEF
    _WINAPI_GETMODULEFILENAME_METHODDEF
    _WINAPI_GETSTDHANDLE_METHODDEF
    _WINAPI_GETVERSION_METHODDEF
    _WINAPI_MAPVIEWOFFILE_METHODDEF
    _WINAPI_OPENFILEMAPPING_METHODDEF
    _WINAPI_OPENPROCESS_METHODDEF
    _WINAPI_PEEKNAMEDPIPE_METHODDEF
    _WINAPI_LCMAPSTRINGEX_METHODDEF
    _WINAPI_READFILE_METHODDEF
    _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF
    _WINAPI_TERMINATEPROCESS_METHODDEF
    _WINAPI_UNMAPVIEWOFFILE_METHODDEF
    _WINAPI_VIRTUALQUERYSIZE_METHODDEF
    _WINAPI_WAITNAMEDPIPE_METHODDEF
    _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF
    _WINAPI_WAITFORSINGLEOBJECT_METHODDEF
    _WINAPI_WRITEFILE_METHODDEF
    _WINAPI_GETACP_METHODDEF
    _WINAPI_GETFILETYPE_METHODDEF
    _WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF
    {NULL, NULL}
};

#define WINAPI_CONSTANT(fmt, con) \
    do { \
        PyObject *value = Py_BuildValue(fmt, con); \
        if (value == NULL) { \
            return -1; \
        } \
        if (PyDict_SetItemString(d, #con, value) < 0) { \
            Py_DECREF(value); \
            return -1; \
        } \
        Py_DECREF(value); \
    } while (0)

static int winapi_exec(PyObject *m)
{
    WinApiState *st = winapi_get_state(m);

    st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(m, &winapi_overlapped_type_spec, NULL);
    if (st->overlapped_type == NULL) {
        return -1;
    }

    if (PyModule_AddType(m, st->overlapped_type) < 0) {
        return -1;
    }

    PyObject *d = PyModule_GetDict(m);

    /* constants */
    WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE);
    WINAPI_CONSTANT(F_DWORD, CREATE_NEW_PROCESS_GROUP);
    WINAPI_CONSTANT(F_DWORD, DUPLICATE_SAME_ACCESS);
    WINAPI_CONSTANT(F_DWORD, DUPLICATE_CLOSE_SOURCE);
    WINAPI_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
    WINAPI_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE);
    WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
    WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA);
    WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
    WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES);
    WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA);
    WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
    WINAPI_CONSTANT(F_DWORD, ERROR_NO_DATA);
    WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES);
    WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED);
    WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
    WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
    WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
    WINAPI_CONSTANT(F_DWORD, FILE_FLAG_FIRST_PIPE_INSTANCE);
    WINAPI_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED);
    WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_READ);
    WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_WRITE);
    WINAPI_CONSTANT(F_DWORD, FILE_MAP_ALL_ACCESS);
    WINAPI_CONSTANT(F_DWORD, FILE_MAP_COPY);
    WINAPI_CONSTANT(F_DWORD, FILE_MAP_EXECUTE);
    WINAPI_CONSTANT(F_DWORD, FILE_MAP_READ);
    WINAPI_CONSTANT(F_DWORD, FILE_MAP_WRITE);
    WINAPI_CONSTANT(F_DWORD, GENERIC_READ);
    WINAPI_CONSTANT(F_DWORD, GENERIC_WRITE);
    WINAPI_CONSTANT(F_DWORD, INFINITE);
    WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE);
    WINAPI_CONSTANT(F_DWORD, MEM_COMMIT);
    WINAPI_CONSTANT(F_DWORD, MEM_FREE);
    WINAPI_CONSTANT(F_DWORD, MEM_IMAGE);
    WINAPI_CONSTANT(F_DWORD, MEM_MAPPED);
    WINAPI_CONSTANT(F_DWORD, MEM_PRIVATE);
    WINAPI_CONSTANT(F_DWORD, MEM_RESERVE);
    WINAPI_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
    WINAPI_CONSTANT(F_DWORD, OPEN_EXISTING);
    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE);
    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READ);
    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READWRITE);
    WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_WRITECOPY);
    WINAPI_CONSTANT(F_DWORD, PAGE_GUARD);
    WINAPI_CONSTANT(F_DWORD, PAGE_NOACCESS);
    WINAPI_CONSTANT(F_DWORD, PAGE_NOCACHE);
    WINAPI_CONSTANT(F_DWORD, PAGE_READONLY);
    WINAPI_CONSTANT(F_DWORD, PAGE_READWRITE);
    WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOMBINE);
    WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOPY);
    WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
    WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
    WINAPI_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
    WINAPI_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
    WINAPI_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
    WINAPI_CONSTANT(F_DWORD, PIPE_WAIT);
    WINAPI_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
    WINAPI_CONSTANT(F_DWORD, SYNCHRONIZE);
    WINAPI_CONSTANT(F_DWORD, PROCESS_DUP_HANDLE);
    WINAPI_CONSTANT(F_DWORD, SEC_COMMIT);
    WINAPI_CONSTANT(F_DWORD, SEC_IMAGE);
    WINAPI_CONSTANT(F_DWORD, SEC_LARGE_PAGES);
    WINAPI_CONSTANT(F_DWORD, SEC_NOCACHE);
    WINAPI_CONSTANT(F_DWORD, SEC_RESERVE);
    WINAPI_CONSTANT(F_DWORD, SEC_WRITECOMBINE);
    WINAPI_CONSTANT(F_DWORD, STARTF_USESHOWWINDOW);
    WINAPI_CONSTANT(F_DWORD, STARTF_USESTDHANDLES);
    WINAPI_CONSTANT(F_DWORD, STD_INPUT_HANDLE);
    WINAPI_CONSTANT(F_DWORD, STD_OUTPUT_HANDLE);
    WINAPI_CONSTANT(F_DWORD, STD_ERROR_HANDLE);
    WINAPI_CONSTANT(F_DWORD, STILL_ACTIVE);
    WINAPI_CONSTANT(F_DWORD, SW_HIDE);
    WINAPI_CONSTANT(F_DWORD, WAIT_OBJECT_0);
    WINAPI_CONSTANT(F_DWORD, WAIT_ABANDONED_0);
    WINAPI_CONSTANT(F_DWORD, WAIT_TIMEOUT);

    WINAPI_CONSTANT(F_DWORD, ABOVE_NORMAL_PRIORITY_CLASS);
    WINAPI_CONSTANT(F_DWORD, BELOW_NORMAL_PRIORITY_CLASS);
    WINAPI_CONSTANT(F_DWORD, HIGH_PRIORITY_CLASS);
    WINAPI_CONSTANT(F_DWORD, IDLE_PRIORITY_CLASS);
    WINAPI_CONSTANT(F_DWORD, NORMAL_PRIORITY_CLASS);
    WINAPI_CONSTANT(F_DWORD, REALTIME_PRIORITY_CLASS);

    WINAPI_CONSTANT(F_DWORD, CREATE_NO_WINDOW);
    WINAPI_CONSTANT(F_DWORD, DETACHED_PROCESS);
    WINAPI_CONSTANT(F_DWORD, CREATE_DEFAULT_ERROR_MODE);
    WINAPI_CONSTANT(F_DWORD, CREATE_BREAKAWAY_FROM_JOB);

    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_UNKNOWN);
    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_DISK);
    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_CHAR);
    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_PIPE);
    WINAPI_CONSTANT(F_DWORD, FILE_TYPE_REMOTE);

    WINAPI_CONSTANT("u", LOCALE_NAME_INVARIANT);
    WINAPI_CONSTANT(F_DWORD, LOCALE_NAME_MAX_LENGTH);
    WINAPI_CONSTANT("u", LOCALE_NAME_SYSTEM_DEFAULT);
    WINAPI_CONSTANT("u", LOCALE_NAME_USER_DEFAULT);

    WINAPI_CONSTANT(F_DWORD, LCMAP_FULLWIDTH);
    WINAPI_CONSTANT(F_DWORD, LCMAP_HALFWIDTH);
    WINAPI_CONSTANT(F_DWORD, LCMAP_HIRAGANA);
    WINAPI_CONSTANT(F_DWORD, LCMAP_KATAKANA);
    WINAPI_CONSTANT(F_DWORD, LCMAP_LINGUISTIC_CASING);
    WINAPI_CONSTANT(F_DWORD, LCMAP_LOWERCASE);
    WINAPI_CONSTANT(F_DWORD, LCMAP_SIMPLIFIED_CHINESE);
    WINAPI_CONSTANT(F_DWORD, LCMAP_TITLECASE);
    WINAPI_CONSTANT(F_DWORD, LCMAP_TRADITIONAL_CHINESE);
    WINAPI_CONSTANT(F_DWORD, LCMAP_UPPERCASE);

    WINAPI_CONSTANT("i", NULL);

    return 0;
}

static PyModuleDef_Slot winapi_slots[] = {
    {Py_mod_exec, winapi_exec},
    {0, NULL}
};

static int
winapi_traverse(PyObject *module, visitproc visit, void *arg)
{
    WinApiState *st = winapi_get_state(module);
    Py_VISIT(st->overlapped_type);
    return 0;
}

static int
winapi_clear(PyObject *module)
{
    WinApiState *st = winapi_get_state(module);
    Py_CLEAR(st->overlapped_type);
    return 0;
}

static void
winapi_free(void *module)
{
    winapi_clear((PyObject *)module);
}

static struct PyModuleDef winapi_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_winapi",
    .m_size = sizeof(WinApiState),
    .m_methods = winapi_functions,
    .m_slots = winapi_slots,
    .m_traverse = winapi_traverse,
    .m_clear = winapi_clear,
    .m_free = winapi_free,
};

PyMODINIT_FUNC
PyInit__winapi(void)
{
    return PyModuleDef_Init(&winapi_module);
}
