/*
 * Copyright (C) 2011-2013 Vinay Sajip.
 * Licensed to PSF under a contributor agreement.
 *
 * Based on the work of:
 *
 * Mark Hammond (original author of Python version)
 * Curt Hagenlocher (job management)
 */

#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
#include <tchar.h>

#define BUFSIZE 256
#define MSGSIZE 1024

/* Build options. */
#define SKIP_PREFIX
#define SEARCH_PATH

/* Error codes */

#define RC_NO_STD_HANDLES   100
#define RC_CREATE_PROCESS   101
#define RC_BAD_VIRTUAL_PATH 102
#define RC_NO_PYTHON        103
#define RC_NO_MEMORY        104
/*
 * SCRIPT_WRAPPER is used to choose one of the variants of an executable built
 * from this source file. If not defined, the PEP 397 Python launcher is built;
 * if defined, a script launcher of the type used by setuptools is built, which
 * looks for a script name related to the executable name and runs that script
 * with the appropriate Python interpreter.
 *
 * SCRIPT_WRAPPER should be undefined in the source, and defined in a VS project
 * which builds the setuptools-style launcher.
 */
#if defined(SCRIPT_WRAPPER)
#define RC_NO_SCRIPT        105
#endif
/*
 * VENV_REDIRECT is used to choose the variant that looks for an adjacent or
 * one-level-higher pyvenv.cfg, and uses its "home" property to locate and
 * launch the original python.exe.
 */
#if defined(VENV_REDIRECT)
#define RC_NO_VENV_CFG      106
#define RC_BAD_VENV_CFG     107
#endif

/* Just for now - static definition */

static FILE * log_fp = NULL;

static wchar_t *
skip_whitespace(wchar_t * p)
{
    while (*p && isspace(*p))
        ++p;
    return p;
}

static void
debug(wchar_t * format, ...)
{
    va_list va;

    if (log_fp != NULL) {
        va_start(va, format);
        vfwprintf_s(log_fp, format, va);
        va_end(va);
    }
}

static void
winerror(int rc, wchar_t * message, int size)
{
    FormatMessageW(
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        message, size, NULL);
}

static void
error(int rc, wchar_t * format, ... )
{
    va_list va;
    wchar_t message[MSGSIZE];
    wchar_t win_message[MSGSIZE];
    int len;

    va_start(va, format);
    len = _vsnwprintf_s(message, MSGSIZE, _TRUNCATE, format, va);
    va_end(va);

    if (rc == 0) {  /* a Windows error */
        winerror(GetLastError(), win_message, MSGSIZE);
        if (len >= 0) {
            _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %ls",
                         win_message);
        }
    }

#if !defined(_WINDOWS)
    fwprintf(stderr, L"%ls\n", message);
#else
    MessageBoxW(NULL, message, L"Python Launcher is sorry to say ...",
               MB_OK);
#endif
    exit(rc);
}

/*
 * This function is here to simplify memory management
 * and to treat blank values as if they are absent.
 */
static wchar_t * get_env(wchar_t * key)
{
    /* This is not thread-safe, just like getenv */
    static wchar_t buf[BUFSIZE];
    DWORD result = GetEnvironmentVariableW(key, buf, BUFSIZE);

    if (result >= BUFSIZE) {
        /* Large environment variable. Accept some leakage */
        wchar_t *buf2 = (wchar_t*)malloc(sizeof(wchar_t) * (result+1));
        if (buf2 == NULL) {
            error(RC_NO_MEMORY, L"Could not allocate environment buffer");
        }
        GetEnvironmentVariableW(key, buf2, result);
        return buf2;
    }

    if (result == 0)
        /* Either some error, e.g. ERROR_ENVVAR_NOT_FOUND,
           or an empty environment variable. */
        return NULL;

    return buf;
}

#if defined(_DEBUG)
/* Do not define EXECUTABLEPATH_VALUE in debug builds as it'll
   never point to the debug build. */
#if defined(_WINDOWS)

#define PYTHON_EXECUTABLE L"pythonw_d.exe"

#else

#define PYTHON_EXECUTABLE L"python_d.exe"

#endif
#else
#if defined(_WINDOWS)

#define PYTHON_EXECUTABLE L"pythonw.exe"
#define EXECUTABLEPATH_VALUE L"WindowedExecutablePath"

#else

#define PYTHON_EXECUTABLE L"python.exe"
#define EXECUTABLEPATH_VALUE L"ExecutablePath"

#endif
#endif

#define MAX_VERSION_SIZE    8

typedef struct {
    wchar_t version[MAX_VERSION_SIZE]; /* m.n */
    int bits;   /* 32 or 64 */
    wchar_t executable[MAX_PATH];
    wchar_t exe_display[MAX_PATH];
} INSTALLED_PYTHON;

/*
 * To avoid messing about with heap allocations, just assume we can allocate
 * statically and never have to deal with more versions than this.
 */
#define MAX_INSTALLED_PYTHONS   100

static INSTALLED_PYTHON installed_pythons[MAX_INSTALLED_PYTHONS];

static size_t num_installed_pythons = 0;

/*
 * To hold SOFTWARE\Python\PythonCore\X.Y...\InstallPath
 * The version name can be longer than MAX_VERSION_SIZE, but will be
 * truncated to just X.Y for comparisons.
 */
#define IP_BASE_SIZE 80
#define IP_VERSION_SIZE 8
#define IP_SIZE (IP_BASE_SIZE + IP_VERSION_SIZE)
#define CORE_PATH L"SOFTWARE\\Python\\PythonCore"
/*
 * Installations from the Microsoft Store will set the same registry keys,
 * but because of a limitation in Windows they cannot be enumerated normally
 * (unless you have no other Python installations... which is probably false
 * because that's the most likely way to get this launcher!)
 * This key is under HKEY_LOCAL_MACHINE
 */
#define LOOKASIDE_PATH L"SOFTWARE\\Microsoft\\AppModel\\Lookaside\\user\\Software\\Python\\PythonCore"

static wchar_t * location_checks[] = {
    L"\\",
    L"\\PCbuild\\win32\\",
    L"\\PCbuild\\amd64\\",
    /* To support early 32bit versions of Python that stuck the build binaries
    * directly in PCbuild... */
    L"\\PCbuild\\",
    NULL
};

static INSTALLED_PYTHON *
find_existing_python(const wchar_t * path)
{
    INSTALLED_PYTHON * result = NULL;
    size_t i;
    INSTALLED_PYTHON * ip;

    for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++, ip++) {
        if (_wcsicmp(path, ip->executable) == 0) {
            result = ip;
            break;
        }
    }
    return result;
}

static INSTALLED_PYTHON *
find_existing_python2(int bits, const wchar_t * version)
{
    INSTALLED_PYTHON * result = NULL;
    size_t i;
    INSTALLED_PYTHON * ip;

    for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++, ip++) {
        if (bits == ip->bits && _wcsicmp(version, ip->version) == 0) {
            result = ip;
            break;
        }
    }
    return result;
}

static void
_locate_pythons_for_key(HKEY root, LPCWSTR subkey, REGSAM flags, int bits,
                        int display_name_only)
{
    HKEY core_root, ip_key;
    LSTATUS status = RegOpenKeyExW(root, subkey, 0, flags, &core_root);
    wchar_t message[MSGSIZE];
    DWORD i;
    size_t n;
    BOOL ok, append_name;
    DWORD type, data_size, attrs;
    INSTALLED_PYTHON * ip, * pip;
    wchar_t ip_version[IP_VERSION_SIZE];
    wchar_t ip_path[IP_SIZE];
    wchar_t * check;
    wchar_t ** checkp;
    wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU";

    if (status != ERROR_SUCCESS)
        debug(L"locate_pythons_for_key: unable to open PythonCore key in %ls\n",
              key_name);
    else {
        ip = &installed_pythons[num_installed_pythons];
        for (i = 0; num_installed_pythons < MAX_INSTALLED_PYTHONS; i++) {
            status = RegEnumKeyW(core_root, i, ip_version, IP_VERSION_SIZE);
            if (status != ERROR_SUCCESS) {
                if (status != ERROR_NO_MORE_ITEMS) {
                    /* unexpected error */
                    winerror(status, message, MSGSIZE);
                    debug(L"Can't enumerate registry key for version %ls: %ls\n",
                          ip_version, message);
                }
                break;
            }
            else {
                wcsncpy_s(ip->version, MAX_VERSION_SIZE, ip_version,
                          MAX_VERSION_SIZE-1);
                /* Still treating version as "x.y" rather than sys.winver
                 * When PEP 514 tags are properly used, we shouldn't need
                 * to strip this off here.
                 */
                check = wcsrchr(ip->version, L'-');
                if (check && !wcscmp(check, L"-32")) {
                    *check = L'\0';
                }
                _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE,
                             L"%ls\\%ls\\InstallPath", subkey, ip_version);
                status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key);
                if (status != ERROR_SUCCESS) {
                    winerror(status, message, MSGSIZE);
                    /* Note: 'message' already has a trailing \n*/
                    debug(L"%ls\\%ls: %ls", key_name, ip_path, message);
                    continue;
                }
                data_size = sizeof(ip->executable) - 1;
                append_name = FALSE;
#ifdef EXECUTABLEPATH_VALUE
                status = RegQueryValueExW(ip_key, EXECUTABLEPATH_VALUE, NULL, &type,
                                          (LPBYTE)ip->executable, &data_size);
#else
                status = ERROR_FILE_NOT_FOUND; /* actual error doesn't matter */
#endif
                if (status != ERROR_SUCCESS || type != REG_SZ || !data_size) {
                    append_name = TRUE;
                    data_size = sizeof(ip->executable) - 1;
                    status = RegQueryValueExW(ip_key, NULL, NULL, &type,
                                              (LPBYTE)ip->executable, &data_size);
                    if (status != ERROR_SUCCESS) {
                        winerror(status, message, MSGSIZE);
                        debug(L"%ls\\%ls: %ls\n", key_name, ip_path, message);
                        RegCloseKey(ip_key);
                        continue;
                    }
                }
                RegCloseKey(ip_key);
                if (type != REG_SZ) {
                    continue;
                }

                data_size = data_size / sizeof(wchar_t) - 1;  /* for NUL */
                if (ip->executable[data_size - 1] == L'\\')
                    --data_size; /* reg value ended in a backslash */
                /* ip->executable is data_size long */
                for (checkp = location_checks; *checkp; ++checkp) {
                    check = *checkp;
                    if (append_name) {
                        _snwprintf_s(&ip->executable[data_size],
                                     MAX_PATH - data_size,
                                     MAX_PATH - data_size,
                                     L"%ls%ls", check, PYTHON_EXECUTABLE);
                    }
                    attrs = GetFileAttributesW(ip->executable);
                    if (attrs == INVALID_FILE_ATTRIBUTES) {
                        winerror(GetLastError(), message, MSGSIZE);
                        debug(L"locate_pythons_for_key: %ls: %ls",
                              ip->executable, message);
                    }
                    else if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
                        debug(L"locate_pythons_for_key: '%ls' is a directory\n",
                              ip->executable);
                    }
                    else if (find_existing_python(ip->executable)) {
                        debug(L"locate_pythons_for_key: %ls: already found\n",
                              ip->executable);
                    }
                    else {
                        /* check the executable type. */
                        if (bits) {
                            ip->bits = bits;
                        } else {
                            ok = GetBinaryTypeW(ip->executable, &attrs);
                            if (!ok) {
                                debug(L"Failure getting binary type: %ls\n",
                                      ip->executable);
                            }
                            else {
                                if (attrs == SCS_64BIT_BINARY)
                                    ip->bits = 64;
                                else if (attrs == SCS_32BIT_BINARY)
                                    ip->bits = 32;
                                else
                                    ip->bits = 0;
                            }
                        }
                        if (ip->bits == 0) {
                            debug(L"locate_pythons_for_key: %ls: \
invalid binary type: %X\n",
                                  ip->executable, attrs);
                        }
                        else {
                            if (display_name_only) {
                                /* display just the executable name. This is
                                 * primarily for the Store installs */
                                const wchar_t *name = wcsrchr(ip->executable, L'\\');
                                if (name) {
                                    wcscpy_s(ip->exe_display, MAX_PATH, name+1);
                                }
                            }
                            if (wcschr(ip->executable, L' ') != NULL) {
                                /* has spaces, so quote, and set original as
                                 * the display name */
                                if (!ip->exe_display[0]) {
                                    wcscpy_s(ip->exe_display, MAX_PATH, ip->executable);
                                }
                                n = wcslen(ip->executable);
                                memmove(&ip->executable[1],
                                        ip->executable, n * sizeof(wchar_t));
                                ip->executable[0] = L'\"';
                                ip->executable[n + 1] = L'\"';
                                ip->executable[n + 2] = L'\0';
                            }
                            debug(L"locate_pythons_for_key: %ls \
is a %dbit executable\n",
                                ip->executable, ip->bits);
                            if (find_existing_python2(ip->bits, ip->version)) {
                                debug(L"locate_pythons_for_key: %ls-%i: already \
found\n", ip->version, ip->bits);
                            }
                            else {
                                ++num_installed_pythons;
                                pip = ip++;
                                if (num_installed_pythons >=
                                    MAX_INSTALLED_PYTHONS)
                                    break;
                            }
                        }
                    }
                }
            }
        }
        RegCloseKey(core_root);
    }
}

static int
compare_pythons(const void * p1, const void * p2)
{
    INSTALLED_PYTHON * ip1 = (INSTALLED_PYTHON *) p1;
    INSTALLED_PYTHON * ip2 = (INSTALLED_PYTHON *) p2;
    /* note reverse sorting on version */
    int result = CompareStringW(LOCALE_INVARIANT, SORT_DIGITSASNUMBERS,
                                ip2->version, -1, ip1->version, -1);
    switch (result) {
    case 0:
        error(0, L"CompareStringW failed");
        return 0;
    case CSTR_LESS_THAN:
        return -1;
    case CSTR_EQUAL:
        return ip2->bits - ip1->bits; /* 64 before 32 */
    case CSTR_GREATER_THAN:
        return 1;
    default:
        return 0; // This should never be reached.
    }
}

static void
locate_pythons_for_key(HKEY root, REGSAM flags)
{
    _locate_pythons_for_key(root, CORE_PATH, flags, 0, FALSE);
}

static void
locate_store_pythons()
{
#if defined(_M_X64)
    /* 64bit process, so look in native registry */
    _locate_pythons_for_key(HKEY_LOCAL_MACHINE, LOOKASIDE_PATH,
                            KEY_READ, 64, TRUE);
#else
    /* 32bit process, so check that we're on 64bit OS */
    BOOL f64 = FALSE;
    if (IsWow64Process(GetCurrentProcess(), &f64) && f64) {
        _locate_pythons_for_key(HKEY_LOCAL_MACHINE, LOOKASIDE_PATH,
                                KEY_READ | KEY_WOW64_64KEY, 64, TRUE);
    }
#endif
}

static void
locate_venv_python()
{
    static wchar_t venv_python[MAX_PATH];
    INSTALLED_PYTHON * ip;
    wchar_t *virtual_env = get_env(L"VIRTUAL_ENV");
    DWORD attrs;

    /* Check for VIRTUAL_ENV environment variable */
    if (virtual_env == NULL || virtual_env[0] == L'\0') {
        return;
    }

    /* Check for a python executable in the venv */
    debug(L"Checking for Python executable in virtual env '%ls'\n", virtual_env);
    _snwprintf_s(venv_python, MAX_PATH, _TRUNCATE,
            L"%ls\\Scripts\\%ls", virtual_env, PYTHON_EXECUTABLE);
    attrs = GetFileAttributesW(venv_python);
    if (attrs == INVALID_FILE_ATTRIBUTES) {
        debug(L"Python executable %ls missing from virtual env\n", venv_python);
        return;
    }

    ip = &installed_pythons[num_installed_pythons++];
    wcscpy_s(ip->executable, MAX_PATH, venv_python);
    ip->bits = 0;
    wcscpy_s(ip->version, MAX_VERSION_SIZE, L"venv");
}

static void
locate_all_pythons()
{
    /* venv Python is highest priority */
    locate_venv_python();
#if defined(_M_X64)
    /* If we are a 64bit process, first hit the 32bit keys. */
    debug(L"locating Pythons in 32bit registry\n");
    locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_32KEY);
    locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_32KEY);
#else
    /* If we are a 32bit process on a 64bit Windows, first hit the 64bit keys.*/
    BOOL f64 = FALSE;
    if (IsWow64Process(GetCurrentProcess(), &f64) && f64) {
        debug(L"locating Pythons in 64bit registry\n");
        locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_64KEY);
        locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_64KEY);
    }
#endif
    /* now hit the "native" key for this process bittedness. */
    debug(L"locating Pythons in native registry\n");
    locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ);
    locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ);
    /* Store-installed Python is lowest priority */
    locate_store_pythons();
    qsort(installed_pythons, num_installed_pythons, sizeof(INSTALLED_PYTHON),
          compare_pythons);
}

static INSTALLED_PYTHON *
find_python_by_version(wchar_t const * wanted_ver)
{
    INSTALLED_PYTHON * result = NULL;
    INSTALLED_PYTHON * ip = installed_pythons;
    size_t i, n;
    size_t wlen = wcslen(wanted_ver);
    int bits = 0;

    if (wcsstr(wanted_ver, L"-32")) {
        bits = 32;
        wlen -= wcslen(L"-32");
    }
    else if (wcsstr(wanted_ver, L"-64")) { /* Added option to select 64 bit explicitly */
        bits = 64;
        wlen -= wcslen(L"-64");
    }
    for (i = 0; i < num_installed_pythons; i++, ip++) {
        n = wcslen(ip->version);
        /*
         * If wlen is greater than 1, we're probably trying to find a specific
         * version and thus want an exact match: 3.1 != 3.10.  Otherwise, we
         * just want a prefix match.
         */
        if ((wlen > 1) && (n != wlen)) {
            continue;
        }
        if (n > wlen) {
            n = wlen;
        }
        if ((wcsncmp(ip->version, wanted_ver, n) == 0) &&
            /* bits == 0 => don't care */
            ((bits == 0) || (ip->bits == bits))) {
            result = ip;
            break;
        }
    }
    return result;
}


static wchar_t appdata_ini_path[MAX_PATH];
static wchar_t launcher_ini_path[MAX_PATH];

/*
 * Get a value either from the environment or a configuration file.
 * The key passed in will either be "python", "python2" or "python3".
 */
static wchar_t *
get_configured_value(wchar_t * key)
{
/*
 * Note: this static value is used to return a configured value
 * obtained either from the environment or configuration file.
 * This should be OK since there wouldn't be any concurrent calls.
 */
    static wchar_t configured_value[MSGSIZE];
    wchar_t * result = NULL;
    wchar_t * found_in = L"environment";
    DWORD size;

    /* First, search the environment. */
    _snwprintf_s(configured_value, MSGSIZE, _TRUNCATE, L"py_%ls", key);
    result = get_env(configured_value);
    if (result == NULL && appdata_ini_path[0]) {
        /* Not in environment: check local configuration. */
        size = GetPrivateProfileStringW(L"defaults", key, NULL,
                                        configured_value, MSGSIZE,
                                        appdata_ini_path);
        if (size > 0) {
            result = configured_value;
            found_in = appdata_ini_path;
        }
    }
    if (result == NULL && launcher_ini_path[0]) {
        /* Not in environment or local: check global configuration. */
        size = GetPrivateProfileStringW(L"defaults", key, NULL,
                                        configured_value, MSGSIZE,
                                        launcher_ini_path);
        if (size > 0) {
            result = configured_value;
            found_in = launcher_ini_path;
        }
    }
    if (result) {
        debug(L"found configured value '%ls=%ls' in %ls\n",
              key, result, found_in ? found_in : L"(unknown)");
    } else {
        debug(L"found no configured value for '%ls'\n", key);
    }
    return result;
}

static INSTALLED_PYTHON *
locate_python(wchar_t * wanted_ver, BOOL from_shebang)
{
    static wchar_t config_key [] = { L"pythonX" };
    static wchar_t * last_char = &config_key[sizeof(config_key) /
                                             sizeof(wchar_t) - 2];
    INSTALLED_PYTHON * result = NULL;
    size_t n = wcslen(wanted_ver);
    wchar_t * configured_value;

    if (num_installed_pythons == 0)
        locate_all_pythons();

    if (n == 1) {   /* just major version specified */
        *last_char = *wanted_ver;
        configured_value = get_configured_value(config_key);
        if (configured_value != NULL)
            wanted_ver = configured_value;
    }
    if (*wanted_ver) {
        result = find_python_by_version(wanted_ver);
        debug(L"search for Python version '%ls' found ", wanted_ver);
        if (result) {
            debug(L"'%ls'\n", result->executable);
        } else {
            debug(L"no interpreter\n");
        }
    }
    else {
        *last_char = L'\0'; /* look for an overall default */
        result = find_python_by_version(L"venv");
        if (result == NULL) {
            configured_value = get_configured_value(config_key);
            if (configured_value)
                result = find_python_by_version(configured_value);
        }
        /* Not found a value yet - try by major version.
         * If we're looking for an interpreter specified in a shebang line,
         * we want to try Python 2 first, then Python 3 (for Unix and backward
         * compatibility). If we're being called interactively, assume the user
         * wants the latest version available, so try Python 3 first, then
         * Python 2.
         */
        if (result == NULL)
            result = find_python_by_version(from_shebang ? L"2" : L"3");
        if (result == NULL)
            result = find_python_by_version(from_shebang ? L"3" : L"2");
        debug(L"search for default Python found ");
        if (result) {
            debug(L"version %ls at '%ls'\n",
                  result->version, result->executable);
        } else {
            debug(L"no interpreter\n");
        }
    }
    return result;
}

#if defined(SCRIPT_WRAPPER)
/*
 * Check for a script located alongside the executable
 */

#if defined(_WINDOWS)
#define SCRIPT_SUFFIX L"-script.pyw"
#else
#define SCRIPT_SUFFIX L"-script.py"
#endif

static wchar_t wrapped_script_path[MAX_PATH];

/* Locate the script being wrapped.
 *
 * This code should store the name of the wrapped script in
 * wrapped_script_path, or terminate the program with an error if there is no
 * valid wrapped script file.
 */
static void
locate_wrapped_script()
{
    wchar_t * p;
    size_t plen;
    DWORD attrs;

    plen = GetModuleFileNameW(NULL, wrapped_script_path, MAX_PATH);
    p = wcsrchr(wrapped_script_path, L'.');
    if (p == NULL) {
        debug(L"GetModuleFileNameW returned value has no extension: %ls\n",
              wrapped_script_path);
        error(RC_NO_SCRIPT, L"Wrapper name '%ls' is not valid.", wrapped_script_path);
    }

    wcsncpy_s(p, MAX_PATH - (p - wrapped_script_path) + 1, SCRIPT_SUFFIX, _TRUNCATE);
    attrs = GetFileAttributesW(wrapped_script_path);
    if (attrs == INVALID_FILE_ATTRIBUTES) {
        debug(L"File '%ls' non-existent\n", wrapped_script_path);
        error(RC_NO_SCRIPT, L"Script file '%ls' is not present.", wrapped_script_path);
    }

    debug(L"Using wrapped script file '%ls'\n", wrapped_script_path);
}
#endif

/*
 * Process creation code
 */

static BOOL
safe_duplicate_handle(HANDLE in, HANDLE * pout)
{
    BOOL ok;
    HANDLE process = GetCurrentProcess();
    DWORD rc;

    *pout = NULL;
    ok = DuplicateHandle(process, in, process, pout, 0, TRUE,
                         DUPLICATE_SAME_ACCESS);
    if (!ok) {
        rc = GetLastError();
        if (rc == ERROR_INVALID_HANDLE) {
            debug(L"DuplicateHandle returned ERROR_INVALID_HANDLE\n");
            ok = TRUE;
        }
        else {
            debug(L"DuplicateHandle returned %d\n", rc);
        }
    }
    return ok;
}

static BOOL WINAPI
ctrl_c_handler(DWORD code)
{
    return TRUE;    /* We just ignore all control events. */
}

static void
run_child(wchar_t * cmdline)
{
    HANDLE job;
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
    DWORD rc;
    BOOL ok;
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;

#if defined(_WINDOWS)
    /*
    When explorer launches a Windows (GUI) application, it displays
    the "app starting" (the "pointer + hourglass") cursor for a number
    of seconds, or until the app does something UI-ish (eg, creating a
    window, or fetching a message).  As this launcher doesn't do this
    directly, that cursor remains even after the child process does these
    things.  We avoid that by doing a simple post+get message.
    See http://bugs.python.org/issue17290 and
    https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running
    */
    MSG msg;

    PostMessage(0, 0, 0, 0);
    GetMessage(&msg, 0, 0, 0);
#endif

    debug(L"run_child: about to run '%ls'\n", cmdline);
    job = CreateJobObject(NULL, NULL);
    ok = QueryInformationJobObject(job, JobObjectExtendedLimitInformation,
                                  &info, sizeof(info), &rc);
    if (!ok || (rc != sizeof(info)) || !job)
        error(RC_CREATE_PROCESS, L"Job information querying failed");
    info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE |
                                             JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
    ok = SetInformationJobObject(job, JobObjectExtendedLimitInformation, &info,
                                 sizeof(info));
    if (!ok)
        error(RC_CREATE_PROCESS, L"Job information setting failed");
    memset(&si, 0, sizeof(si));
    GetStartupInfoW(&si);
    ok = safe_duplicate_handle(GetStdHandle(STD_INPUT_HANDLE), &si.hStdInput);
    if (!ok)
        error(RC_NO_STD_HANDLES, L"stdin duplication failed");
    ok = safe_duplicate_handle(GetStdHandle(STD_OUTPUT_HANDLE), &si.hStdOutput);
    if (!ok)
        error(RC_NO_STD_HANDLES, L"stdout duplication failed");
    ok = safe_duplicate_handle(GetStdHandle(STD_ERROR_HANDLE), &si.hStdError);
    if (!ok)
        error(RC_NO_STD_HANDLES, L"stderr duplication failed");

    ok = SetConsoleCtrlHandler(ctrl_c_handler, TRUE);
    if (!ok)
        error(RC_CREATE_PROCESS, L"control handler setting failed");

    si.dwFlags = STARTF_USESTDHANDLES;
    ok = CreateProcessW(NULL, cmdline, NULL, NULL, TRUE,
                        0, NULL, NULL, &si, &pi);
    if (!ok)
        error(RC_CREATE_PROCESS, L"Unable to create process using '%ls'", cmdline);
    AssignProcessToJobObject(job, pi.hProcess);
    CloseHandle(pi.hThread);
    WaitForSingleObjectEx(pi.hProcess, INFINITE, FALSE);
    ok = GetExitCodeProcess(pi.hProcess, &rc);
    if (!ok)
        error(RC_CREATE_PROCESS, L"Failed to get exit code of process");
    debug(L"child process exit code: %d\n", rc);
    exit(rc);
}

static void
invoke_child(wchar_t * executable, wchar_t * suffix, wchar_t * cmdline)
{
    wchar_t * child_command;
    size_t child_command_size;
    BOOL no_suffix = (suffix == NULL) || (*suffix == L'\0');
    BOOL no_cmdline = (*cmdline == L'\0');

    if (no_suffix && no_cmdline)
        run_child(executable);
    else {
        if (no_suffix) {
            /* add 2 for space separator + terminating NUL. */
            child_command_size = wcslen(executable) + wcslen(cmdline) + 2;
        }
        else {
            /* add 3 for 2 space separators + terminating NUL. */
            child_command_size = wcslen(executable) + wcslen(suffix) +
                                    wcslen(cmdline) + 3;
        }
        child_command = calloc(child_command_size, sizeof(wchar_t));
        if (child_command == NULL)
            error(RC_CREATE_PROCESS, L"unable to allocate %zd bytes for child command.",
                  child_command_size);
        if (no_suffix)
            _snwprintf_s(child_command, child_command_size,
                         child_command_size - 1, L"%ls %ls",
                         executable, cmdline);
        else
            _snwprintf_s(child_command, child_command_size,
                         child_command_size - 1, L"%ls %ls %ls",
                         executable, suffix, cmdline);
        run_child(child_command);
        free(child_command);
    }
}

typedef struct {
    wchar_t *shebang;
    BOOL search;
} SHEBANG;

static SHEBANG builtin_virtual_paths [] = {
    { L"/usr/bin/env python", TRUE },
    { L"/usr/bin/python", FALSE },
    { L"/usr/local/bin/python", FALSE },
    { L"python", FALSE },
    { NULL, FALSE },
};

/* For now, a static array of commands. */

#define MAX_COMMANDS 100

typedef struct {
    wchar_t key[MAX_PATH];
    wchar_t value[MSGSIZE];
} COMMAND;

static COMMAND commands[MAX_COMMANDS];
static int num_commands = 0;

#if defined(SKIP_PREFIX)

static wchar_t * builtin_prefixes [] = {
    /* These must be in an order that the longest matches should be found,
     * i.e. if the prefix is "/usr/bin/env ", it should match that entry
     * *before* matching "/usr/bin/".
     */
    L"/usr/bin/env ",
    L"/usr/bin/",
    L"/usr/local/bin/",
    NULL
};

static wchar_t * skip_prefix(wchar_t * name)
{
    wchar_t ** pp = builtin_prefixes;
    wchar_t * result = name;
    wchar_t * p;
    size_t n;

    for (; p = *pp; pp++) {
        n = wcslen(p);
        if (_wcsnicmp(p, name, n) == 0) {
            result += n;   /* skip the prefix */
            if (p[n - 1] == L' ') /* No empty strings in table, so n > 1 */
                result = skip_whitespace(result);
            break;
        }
    }
    return result;
}

#endif

#if defined(SEARCH_PATH)

static COMMAND path_command;

static COMMAND * find_on_path(wchar_t * name)
{
    wchar_t * pathext;
    size_t    varsize;
    wchar_t * context = NULL;
    wchar_t * extension;
    COMMAND * result = NULL;
    DWORD     len;
    errno_t   rc;

    wcscpy_s(path_command.key, MAX_PATH, name);
    if (wcschr(name, L'.') != NULL) {
        /* assume it has an extension. */
        len = SearchPathW(NULL, name, NULL, MSGSIZE, path_command.value, NULL);
        if (len) {
            result = &path_command;
        }
    }
    else {
        /* No extension - search using registered extensions. */
        rc = _wdupenv_s(&pathext, &varsize, L"PATHEXT");
        if (rc == 0) {
            extension = wcstok_s(pathext, L";", &context);
            while (extension) {
                len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL);
                if (len) {
                    result = &path_command;
                    break;
                }
                extension = wcstok_s(NULL, L";", &context);
            }
            free(pathext);
        }
    }
    return result;
}

#endif

static COMMAND * find_command(wchar_t * name)
{
    COMMAND * result = NULL;
    COMMAND * cp = commands;
    int i;

    for (i = 0; i < num_commands; i++, cp++) {
        if (_wcsicmp(cp->key, name) == 0) {
            result = cp;
            break;
        }
    }
#if defined(SEARCH_PATH)
    if (result == NULL)
        result = find_on_path(name);
#endif
    return result;
}

static void
update_command(COMMAND * cp, wchar_t * name, wchar_t * cmdline)
{
    wcsncpy_s(cp->key, MAX_PATH, name, _TRUNCATE);
    wcsncpy_s(cp->value, MSGSIZE, cmdline, _TRUNCATE);
}

static void
add_command(wchar_t * name, wchar_t * cmdline)
{
    if (num_commands >= MAX_COMMANDS) {
        debug(L"can't add %ls = '%ls': no room\n", name, cmdline);
    }
    else {
        COMMAND * cp = &commands[num_commands++];

        update_command(cp, name, cmdline);
    }
}

static void
read_config_file(wchar_t * config_path)
{
    wchar_t keynames[MSGSIZE];
    wchar_t value[MSGSIZE];
    DWORD read;
    wchar_t * key;
    COMMAND * cp;
    wchar_t * cmdp;

    read = GetPrivateProfileStringW(L"commands", NULL, NULL, keynames, MSGSIZE,
                                    config_path);
    if (read == MSGSIZE - 1) {
        debug(L"read_commands: %ls: not enough space for names\n", config_path);
    }
    key = keynames;
    while (*key) {
        read = GetPrivateProfileStringW(L"commands", key, NULL, value, MSGSIZE,
                                       config_path);
        if (read == MSGSIZE - 1) {
            debug(L"read_commands: %ls: not enough space for %ls\n",
                  config_path, key);
        }
        cmdp = skip_whitespace(value);
        if (*cmdp) {
            cp = find_command(key);
            if (cp == NULL)
                add_command(key, value);
            else
                update_command(cp, key, value);
        }
        key += wcslen(key) + 1;
    }
}

static void read_commands()
{
    if (launcher_ini_path[0])
        read_config_file(launcher_ini_path);
    if (appdata_ini_path[0])
        read_config_file(appdata_ini_path);
}

static BOOL
parse_shebang(wchar_t * shebang_line, int nchars, wchar_t ** command,
              wchar_t ** suffix, BOOL *search)
{
    BOOL rc = FALSE;
    SHEBANG * vpp;
    size_t plen;
    wchar_t * p;
    wchar_t zapped;
    wchar_t * endp = shebang_line + nchars - 1;
    COMMAND * cp;
    wchar_t * skipped;

    *command = NULL;    /* failure return */
    *suffix = NULL;
    *search = FALSE;

    if ((*shebang_line++ == L'#') && (*shebang_line++ == L'!')) {
        shebang_line = skip_whitespace(shebang_line);
        if (*shebang_line) {
            *command = shebang_line;
            for (vpp = builtin_virtual_paths; vpp->shebang; ++vpp) {
                plen = wcslen(vpp->shebang);
                if (wcsncmp(shebang_line, vpp->shebang, plen) == 0) {
                    rc = TRUE;
                    *search = vpp->search;
                    /* We can do this because all builtin commands contain
                     * "python".
                     */
                    *command = wcsstr(shebang_line, L"python");
                    break;
                }
            }
            if (vpp->shebang == NULL) {
                /*
                 * Not found in builtins - look in customized commands.
                 *
                 * We can't permanently modify the shebang line in case
                 * it's not a customized command, but we can temporarily
                 * stick a NUL after the command while searching for it,
                 * then put back the char we zapped.
                 */
#if defined(SKIP_PREFIX)
                skipped = skip_prefix(shebang_line);
#else
                skipped = shebang_line;
#endif
                p = wcspbrk(skipped, L" \t\r\n");
                if (p != NULL) {
                    zapped = *p;
                    *p = L'\0';
                }
                cp = find_command(skipped);
                if (p != NULL)
                    *p = zapped;
                if (cp != NULL) {
                    *command = cp->value;
                    if (p != NULL)
                        *suffix = skip_whitespace(p);
                }
            }
            /* remove trailing whitespace */
            while ((endp > shebang_line) && isspace(*endp))
                --endp;
            if (endp > shebang_line)
                endp[1] = L'\0';
        }
    }
    return rc;
}

/* #define CP_UTF8             65001 defined in winnls.h */
#define CP_UTF16LE          1200
#define CP_UTF16BE          1201
#define CP_UTF32LE          12000
#define CP_UTF32BE          12001

typedef struct {
    int length;
    char sequence[4];
    UINT code_page;
} BOM;

/*
 * Strictly, we don't need to handle UTF-16 and UTF-32, since Python itself
 * doesn't. Never mind, one day it might - there's no harm leaving it in.
 */
static BOM BOMs[] = {
    { 3, { 0xEF, 0xBB, 0xBF }, CP_UTF8 },           /* UTF-8 - keep first */
    /* Test UTF-32LE before UTF-16LE since UTF-16LE BOM is a prefix
     * of UTF-32LE BOM. */
    { 4, { 0xFF, 0xFE, 0x00, 0x00 }, CP_UTF32LE },  /* UTF-32LE */
    { 4, { 0x00, 0x00, 0xFE, 0xFF }, CP_UTF32BE },  /* UTF-32BE */
    { 2, { 0xFF, 0xFE }, CP_UTF16LE },              /* UTF-16LE */
    { 2, { 0xFE, 0xFF }, CP_UTF16BE },              /* UTF-16BE */
    { 0 }                                           /* sentinel */
};

static BOM *
find_BOM(char * buffer)
{
/*
 * Look for a BOM in the input and return a pointer to the
 * corresponding structure, or NULL if not found.
 */
    BOM * result = NULL;
    BOM *bom;

    for (bom = BOMs; bom->length; bom++) {
        if (strncmp(bom->sequence, buffer, bom->length) == 0) {
            result = bom;
            break;
        }
    }
    return result;
}

static char *
find_terminator(char * buffer, int len, BOM *bom)
{
    char * result = NULL;
    char * end = buffer + len;
    char  * p;
    char c;
    int cp;

    for (p = buffer; p < end; p++) {
        c = *p;
        if (c == '\r') {
            result = p;
            break;
        }
        if (c == '\n') {
            result = p;
            break;
        }
    }
    if (result != NULL) {
        cp = bom->code_page;

        /* adjustments to include all bytes of the char */
        /* no adjustment needed for UTF-8 or big endian */
        if (cp == CP_UTF16LE)
            ++result;
        else if (cp == CP_UTF32LE)
            result += 3;
        ++result; /* point just past terminator */
    }
    return result;
}

static BOOL
validate_version(wchar_t * p)
{
    /*
    Version information should start with the major version,
    Optionally followed by a period and a minor version,
    Optionally followed by a minus and one of 32 or 64.
    Valid examples:
      2
      3
      2.7
      3.6
      2.7-32
      The intent is to add to the valid patterns:
      3.10
      3-32
      3.6-64
      3-64
    */
    BOOL result = (p != NULL); /* Default to False if null pointer. */

    result = result && iswdigit(*p);  /* Result = False if first string element is not a digit. */

    while (result && iswdigit(*p))   /* Require a major version */
        ++p;  /* Skip all leading digit(s) */
    if (result && (*p == L'.'))     /* Allow . for major minor separator.*/
    {
        result = iswdigit(*++p);     /* Must be at least one digit */
        while (result && iswdigit(*++p)) ; /* Skip any more Digits */
    }
    if (result && (*p == L'-')) {   /* Allow - for Bits Separator */
        switch(*++p){
        case L'3':                            /* 3 is OK */
            result = (*++p == L'2') && !*++p; /* only if followed by 2 and ended.*/
            break;
        case L'6':                            /* 6 is OK */
            result = (*++p == L'4') && !*++p; /* only if followed by 4 and ended.*/
            break;
        default:
            result = FALSE;
            break;
        }
    }
    result = result && !*p; /* Must have reached EOS */
    return result;

}

typedef struct {
    unsigned short min;
    unsigned short max;
    wchar_t version[MAX_VERSION_SIZE];
} PYC_MAGIC;

static PYC_MAGIC magic_values[] = {
    { 50823, 50823, L"2.0" },
    { 60202, 60202, L"2.1" },
    { 60717, 60717, L"2.2" },
    { 62011, 62021, L"2.3" },
    { 62041, 62061, L"2.4" },
    { 62071, 62131, L"2.5" },
    { 62151, 62161, L"2.6" },
    { 62171, 62211, L"2.7" },
    { 3000, 3131, L"3.0" },
    { 3141, 3151, L"3.1" },
    { 3160, 3180, L"3.2" },
    { 3190, 3230, L"3.3" },
    { 3250, 3310, L"3.4" },
    { 3320, 3351, L"3.5" },
    { 3360, 3379, L"3.6" },
    { 3390, 3399, L"3.7" },
    { 3400, 3419, L"3.8" },
    { 3420, 3429, L"3.9" },
    { 3430, 3439, L"3.10" },
    { 0 }
};

static INSTALLED_PYTHON *
find_by_magic(unsigned short magic)
{
    INSTALLED_PYTHON * result = NULL;
    PYC_MAGIC * mp;

    for (mp = magic_values; mp->min; mp++) {
        if ((magic >= mp->min) && (magic <= mp->max)) {
            result = locate_python(mp->version, FALSE);
            if (result != NULL)
                break;
        }
    }
    return result;
}

static void
maybe_handle_shebang(wchar_t ** argv, wchar_t * cmdline)
{
/*
 * Look for a shebang line in the first argument.  If found
 * and we spawn a child process, this never returns.  If it
 * does return then we process the args "normally".
 *
 * argv[0] might be a filename with a shebang.
 */
    FILE * fp;
    errno_t rc = _wfopen_s(&fp, *argv, L"rb");
    char buffer[BUFSIZE];
    wchar_t shebang_line[BUFSIZE + 1];
    size_t read;
    char *p;
    char * start;
    char * shebang_alias = (char *) shebang_line;
    BOM* bom;
    int i, j, nchars = 0;
    int header_len;
    BOOL is_virt;
    BOOL search;
    wchar_t * command;
    wchar_t * suffix;
    COMMAND *cmd = NULL;
    INSTALLED_PYTHON * ip;

    if (rc == 0) {
        read = fread(buffer, sizeof(char), BUFSIZE, fp);
        debug(L"maybe_handle_shebang: read %zd bytes\n", read);
        fclose(fp);

        if ((read >= 4) && (buffer[3] == '\n') && (buffer[2] == '\r')) {
            ip = find_by_magic((((unsigned char)buffer[1]) << 8 |
                                (unsigned char)buffer[0]) & 0xFFFF);
            if (ip != NULL) {
                debug(L"script file is compiled against Python %ls\n",
                      ip->version);
                invoke_child(ip->executable, NULL, cmdline);
            }
        }
        /* Look for BOM */
        bom = find_BOM(buffer);
        if (bom == NULL) {
            start = buffer;
            debug(L"maybe_handle_shebang: BOM not found, using UTF-8\n");
            bom = BOMs; /* points to UTF-8 entry - the default */
        }
        else {
            debug(L"maybe_handle_shebang: BOM found, code page %u\n",
                  bom->code_page);
            start = &buffer[bom->length];
        }
        p = find_terminator(start, BUFSIZE, bom);
        /*
         * If no CR or LF was found in the heading,
         * we assume it's not a shebang file.
         */
        if (p == NULL) {
            debug(L"maybe_handle_shebang: No line terminator found\n");
        }
        else {
            /*
             * Found line terminator - parse the shebang.
             *
             * Strictly, we don't need to handle UTF-16 anf UTF-32,
             * since Python itself doesn't.
             * Never mind, one day it might.
             */
            header_len = (int) (p - start);
            switch(bom->code_page) {
            case CP_UTF8:
                nchars = MultiByteToWideChar(bom->code_page,
                                             0,
                                             start, header_len, shebang_line,
                                             BUFSIZE);
                break;
            case CP_UTF16BE:
                if (header_len % 2 != 0) {
                    debug(L"maybe_handle_shebang: UTF-16BE, but an odd number \
of bytes: %d\n", header_len);
                    /* nchars = 0; Not needed - initialised to 0. */
                }
                else {
                    for (i = header_len; i > 0; i -= 2) {
                        shebang_alias[i - 1] = start[i - 2];
                        shebang_alias[i - 2] = start[i - 1];
                    }
                    nchars = header_len / sizeof(wchar_t);
                }
                break;
            case CP_UTF16LE:
                if ((header_len % 2) != 0) {
                    debug(L"UTF-16LE, but an odd number of bytes: %d\n",
                          header_len);
                    /* nchars = 0; Not needed - initialised to 0. */
                }
                else {
                    /* no actual conversion needed. */
                    memcpy(shebang_line, start, header_len);
                    nchars = header_len / sizeof(wchar_t);
                }
                break;
            case CP_UTF32BE:
                if (header_len % 4 != 0) {
                    debug(L"UTF-32BE, but not divisible by 4: %d\n",
                          header_len);
                    /* nchars = 0; Not needed - initialised to 0. */
                }
                else {
                    for (i = header_len, j = header_len / 2; i > 0; i -= 4,
                                                                    j -= 2) {
                        shebang_alias[j - 1] = start[i - 2];
                        shebang_alias[j - 2] = start[i - 1];
                    }
                    nchars = header_len / sizeof(wchar_t);
                }
                break;
            case CP_UTF32LE:
                if (header_len % 4 != 0) {
                    debug(L"UTF-32LE, but not divisible by 4: %d\n",
                          header_len);
                    /* nchars = 0; Not needed - initialised to 0. */
                }
                else {
                    for (i = header_len, j = header_len / 2; i > 0; i -= 4,
                                                                    j -= 2) {
                        shebang_alias[j - 1] = start[i - 3];
                        shebang_alias[j - 2] = start[i - 4];
                    }
                    nchars = header_len / sizeof(wchar_t);
                }
                break;
            }
            if (nchars > 0) {
                shebang_line[--nchars] = L'\0';
                is_virt = parse_shebang(shebang_line, nchars, &command,
                                        &suffix, &search);
                if (command != NULL) {
                    debug(L"parse_shebang: found command: %ls\n", command);
                    if (!is_virt) {
                        invoke_child(command, suffix, cmdline);
                    }
                    else {
                        suffix = wcschr(command, L' ');
                        if (suffix != NULL) {
                            *suffix++ = L'\0';
                            suffix = skip_whitespace(suffix);
                        }
                        if (wcsncmp(command, L"python", 6))
                            error(RC_BAD_VIRTUAL_PATH, L"Unknown virtual \
path '%ls'", command);
                        command += 6;   /* skip past "python" */
                        if (search && ((*command == L'\0') || isspace(*command))) {
                            /* Command is eligible for path search, and there
                             * is no version specification.
                             */
                            debug(L"searching PATH for python executable\n");
                            cmd = find_on_path(PYTHON_EXECUTABLE);
                            debug(L"Python on path: %ls\n", cmd ? cmd->value : L"<not found>");
                            if (cmd) {
                                debug(L"located python on PATH: %ls\n", cmd->value);
                                invoke_child(cmd->value, suffix, cmdline);
                                /* Exit here, as we have found the command */
                                return;
                            }
                            /* FALL THROUGH: No python found on PATH, so fall
                             * back to locating the correct installed python.
                             */
                        }
                        if (*command && !validate_version(command))
                            error(RC_BAD_VIRTUAL_PATH, L"Invalid version \
specification: '%ls'.\nIn the first line of the script, 'python' needs to be \
followed by a valid version specifier.\nPlease check the documentation.",
                                  command);
                        /* TODO could call validate_version(command) */
                        ip = locate_python(command, TRUE);
                        if (ip == NULL) {
                            error(RC_NO_PYTHON, L"Requested Python version \
(%ls) is not installed", command);
                        }
                        else {
                            invoke_child(ip->executable, suffix, cmdline);
                        }
                    }
                }
            }
        }
    }
}

static wchar_t *
skip_me(wchar_t * cmdline)
{
    BOOL quoted;
    wchar_t c;
    wchar_t * result = cmdline;

    quoted = cmdline[0] == L'\"';
    if (!quoted)
        c = L' ';
    else {
        c = L'\"';
        ++result;
    }
    result = wcschr(result, c);
    if (result == NULL) /* when, for example, just exe name on command line */
        result = L"";
    else {
        ++result; /* skip past space or closing quote */
        result = skip_whitespace(result);
    }
    return result;
}

static DWORD version_high = 0;
static DWORD version_low = 0;

static void
get_version_info(wchar_t * version_text, size_t size)
{
    WORD maj, min, rel, bld;

    if (!version_high && !version_low)
        wcsncpy_s(version_text, size, L"0.1", _TRUNCATE);   /* fallback */
    else {
        maj = HIWORD(version_high);
        min = LOWORD(version_high);
        rel = HIWORD(version_low);
        bld = LOWORD(version_low);
        _snwprintf_s(version_text, size, _TRUNCATE, L"%d.%d.%d.%d", maj,
                     min, rel, bld);
    }
}

static void
show_help_text(wchar_t ** argv)
{
    wchar_t version_text [MAX_PATH];
#if defined(_M_X64)
    BOOL canDo64bit = TRUE;
#else
    /* If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. */
    BOOL canDo64bit = FALSE;
    IsWow64Process(GetCurrentProcess(), &canDo64bit);
#endif

    get_version_info(version_text, MAX_PATH);
    fwprintf(stdout, L"\
Python Launcher for Windows Version %ls\n\n", version_text);
    fwprintf(stdout, L"\
usage:\n\
%ls [launcher-args] [python-args] [script [script-args]]\n\n", argv[0]);
    fputws(L"\
Launcher arguments:\n\n\
-2     : Launch the latest Python 2.x version\n\
-3     : Launch the latest Python 3.x version\n\
-X.Y   : Launch the specified Python version\n", stdout);
    if (canDo64bit) {
        fputws(L"\
     The above all default to 64 bit if a matching 64 bit python is present.\n\
-X.Y-32: Launch the specified 32bit Python version\n\
-X-32  : Launch the latest 32bit Python X version\n\
-X.Y-64: Launch the specified 64bit Python version\n\
-X-64  : Launch the latest 64bit Python X version", stdout);
    }
    fputws(L"\n-0  --list       : List the available pythons", stdout);
    fputws(L"\n-0p --list-paths : List with paths", stdout);
    fputws(L"\n\n If no script is specified the specified interpreter is opened.", stdout);
    fputws(L"\nIf an exact version is not given, using the latest version can be overridden by", stdout);
    fputws(L"\nany of the following, (in priority order):", stdout);
    fputws(L"\n An active virtual environment", stdout);
    fputws(L"\n A shebang line in the script (if present)", stdout);
    fputws(L"\n With -2 or -3 flag a matching PY_PYTHON2 or PY_PYTHON3 Environment variable", stdout);
    fputws(L"\n A PY_PYTHON Environment variable", stdout);
    fputws(L"\n From [defaults] in py.ini in your %LOCALAPPDATA%\\py.ini", stdout);
    fputws(L"\n From [defaults] in py.ini beside py.exe (use `where py` to locate)", stdout);
    fputws(L"\n\nThe following help text is from Python:\n\n", stdout);
    fflush(stdout);
}

static BOOL
show_python_list(wchar_t ** argv)
{
    /*
     * Display options -0
     */
    INSTALLED_PYTHON * result = NULL;
    INSTALLED_PYTHON * ip = installed_pythons; /* List of installed pythons */
    INSTALLED_PYTHON * defpy = locate_python(L"", FALSE);
    size_t i = 0;
    wchar_t *p = argv[1];
    wchar_t *ver_fmt = L"-%ls-%d";
    wchar_t *fmt = L"\n %ls";
    wchar_t *defind = L" *"; /* Default indicator */

    /*
    * Output informational messages to stderr to keep output
    * clean for use in pipes, etc.
    */
    fwprintf(stderr,
             L"Installed Pythons found by %s Launcher for Windows", argv[0]);
    if (!_wcsicmp(p, L"-0p") || !_wcsicmp(p, L"--list-paths"))
        fmt = L"\n %-15ls%ls"; /* include path */

    if (num_installed_pythons == 0) /* We have somehow got here without searching for pythons */
        locate_all_pythons(); /* Find them, Populates installed_pythons */

    if (num_installed_pythons == 0) /* No pythons found */
        fwprintf(stderr, L"\nNo Installed Pythons Found!");
    else
    {
        for (i = 0; i < num_installed_pythons; i++, ip++) {
            wchar_t version[BUFSIZ];
            if (wcscmp(ip->version, L"venv") == 0) {
                wcscpy_s(version, BUFSIZ, L"(venv)");
            }
            else {
                swprintf_s(version, BUFSIZ, ver_fmt, ip->version, ip->bits);
            }

            if (ip->exe_display[0]) {
                fwprintf(stdout, fmt, version, ip->exe_display);
            }
            else {
                fwprintf(stdout, fmt, version, ip->executable);
            }
            /* If there is a default indicate it */
            if (defpy == ip)
                fwprintf(stderr, defind);
        }
    }

    if ((defpy == NULL) && (num_installed_pythons > 0))
        /* We have pythons but none is the default */
        fwprintf(stderr, L"\n\nCan't find a Default Python.\n\n");
    else
        fwprintf(stderr, L"\n\n"); /* End with a blank line */
    return FALSE; /* If this has been called we cannot continue */
}

#if defined(VENV_REDIRECT)

static int
find_home_value(const char *buffer, const char **start, DWORD *length)
{
    for (const char *s = strstr(buffer, "home"); s; s = strstr(s + 1, "\nhome")) {
        if (*s == '\n') {
            ++s;
        }
        for (int i = 4; i > 0 && *s; --i, ++s);

        while (*s && iswspace(*s)) {
            ++s;
        }
        if (*s != L'=') {
            continue;
        }

        do {
            ++s;
        } while (*s && iswspace(*s));

        *start = s;
        char *nl = strchr(s, '\n');
        if (nl) {
            *length = (DWORD)((ptrdiff_t)nl - (ptrdiff_t)s);
        } else {
            *length = (DWORD)strlen(s);
        }
        return 1;
    }
    return 0;
}
#endif

static wchar_t *
wcsdup_pad(const wchar_t *s, int padding, int *newlen)
{
    size_t len = wcslen(s);
    len += 1 + padding;
    wchar_t *r = (wchar_t *)malloc(len * sizeof(wchar_t));
    if (!r) {
        return NULL;
    }
    if (wcscpy_s(r, len, s)) {
        free(r);
        return NULL;
    }
    *newlen = len < MAXINT ? (int)len : MAXINT;
    return r;
}

static wchar_t *
get_process_name()
{
    DWORD bufferLen = MAX_PATH;
    DWORD len = bufferLen;
    wchar_t *r = NULL;

    while (!r) {
        r = (wchar_t *)malloc(bufferLen * sizeof(wchar_t));
        if (!r) {
            error(RC_NO_MEMORY, L"out of memory");
            return NULL;
        }
        len = GetModuleFileNameW(NULL, r, bufferLen);
        if (len == 0) {
            free(r);
            error(0, L"Failed to get module name");
            return NULL;
        } else if (len == bufferLen &&
                   GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            free(r);
            r = NULL;
            bufferLen *= 2;
        }
    }

    return r;
}

static int
process(int argc, wchar_t ** argv)
{
    wchar_t * wp;
    wchar_t * command;
    wchar_t * executable;
    wchar_t * p;
    wchar_t * argv0;
    int rc = 0;
    INSTALLED_PYTHON * ip;
    BOOL valid;
    DWORD size, attrs;
    wchar_t message[MSGSIZE];
    void * version_data;
    VS_FIXEDFILEINFO * file_info;
    UINT block_size;
#if defined(VENV_REDIRECT)
    wchar_t * venv_cfg_path;
    int newlen;
#elif defined(SCRIPT_WRAPPER)
    wchar_t * newcommand;
    wchar_t * av[2];
    int newlen;
    HRESULT hr;
    int index;
#else
    HRESULT hr;
    int index;
#endif

    setvbuf(stderr, (char *)NULL, _IONBF, 0);
    wp = get_env(L"PYLAUNCH_DEBUG");
    if ((wp != NULL) && (*wp != L'\0'))
        log_fp = stderr;

#if defined(_M_X64)
    debug(L"launcher build: 64bit\n");
#else
    debug(L"launcher build: 32bit\n");
#endif
#if defined(_WINDOWS)
    debug(L"launcher executable: Windows\n");
#else
    debug(L"launcher executable: Console\n");
#endif
#if !defined(VENV_REDIRECT)
    /* Get the local appdata folder (non-roaming) */
    hr = SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA,
                          NULL, 0, appdata_ini_path);
    if (hr != S_OK) {
        debug(L"SHGetFolderPath failed: %X\n", hr);
        appdata_ini_path[0] = L'\0';
    }
    else {
        wcsncat_s(appdata_ini_path, MAX_PATH, L"\\py.ini", _TRUNCATE);
        attrs = GetFileAttributesW(appdata_ini_path);
        if (attrs == INVALID_FILE_ATTRIBUTES) {
            debug(L"File '%ls' non-existent\n", appdata_ini_path);
            appdata_ini_path[0] = L'\0';
        } else {
            debug(L"Using local configuration file '%ls'\n", appdata_ini_path);
        }
    }
#endif
    argv0 = get_process_name();
    size = GetFileVersionInfoSizeW(argv0, &size);
    if (size == 0) {
        winerror(GetLastError(), message, MSGSIZE);
        debug(L"GetFileVersionInfoSize failed: %ls\n", message);
    }
    else {
        version_data = malloc(size);
        if (version_data) {
            valid = GetFileVersionInfoW(argv0, 0, size,
                                        version_data);
            if (!valid)
                debug(L"GetFileVersionInfo failed: %X\n", GetLastError());
            else {
                valid = VerQueryValueW(version_data, L"\\",
                                       (LPVOID *) &file_info, &block_size);
                if (!valid)
                    debug(L"VerQueryValue failed: %X\n", GetLastError());
                else {
                    version_high = file_info->dwFileVersionMS;
                    version_low = file_info->dwFileVersionLS;
                }
            }
            free(version_data);
        }
    }

#if defined(VENV_REDIRECT)
    /* Allocate some extra space for new filenames */
    venv_cfg_path = wcsdup_pad(argv0, 32, &newlen);
    if (!venv_cfg_path) {
        error(RC_NO_MEMORY, L"Failed to copy module name");
    }
    p = wcsrchr(venv_cfg_path, L'\\');

    if (p == NULL) {
        error(RC_NO_VENV_CFG, L"No pyvenv.cfg file");
    }
    p[0] = L'\0';
    wcscat_s(venv_cfg_path, newlen, L"\\pyvenv.cfg");
    attrs = GetFileAttributesW(venv_cfg_path);
    if (attrs == INVALID_FILE_ATTRIBUTES) {
        debug(L"File '%ls' non-existent\n", venv_cfg_path);
        p[0] = '\0';
        p = wcsrchr(venv_cfg_path, L'\\');
        if (p != NULL) {
            p[0] = '\0';
            wcscat_s(venv_cfg_path, newlen, L"\\pyvenv.cfg");
            attrs = GetFileAttributesW(venv_cfg_path);
            if (attrs == INVALID_FILE_ATTRIBUTES) {
                debug(L"File '%ls' non-existent\n", venv_cfg_path);
                error(RC_NO_VENV_CFG, L"No pyvenv.cfg file");
            }
        }
    }
    debug(L"Using venv configuration file '%ls'\n", venv_cfg_path);
#else
    /* Allocate some extra space for new filenames */
    if (wcscpy_s(launcher_ini_path, MAX_PATH, argv0)) {
        error(RC_NO_MEMORY, L"Failed to copy module name");
    }
    p = wcsrchr(launcher_ini_path, L'\\');

    if (p == NULL) {
        debug(L"GetModuleFileNameW returned value has no backslash: %ls\n",
              launcher_ini_path);
        launcher_ini_path[0] = L'\0';
    }
    else {
        p[0] = L'\0';
        wcscat_s(launcher_ini_path, MAX_PATH, L"\\py.ini");
        attrs = GetFileAttributesW(launcher_ini_path);
        if (attrs == INVALID_FILE_ATTRIBUTES) {
            debug(L"File '%ls' non-existent\n", launcher_ini_path);
            launcher_ini_path[0] = L'\0';
        } else {
            debug(L"Using global configuration file '%ls'\n", launcher_ini_path);
        }
    }
#endif

    command = skip_me(GetCommandLineW());
    debug(L"Called with command line: %ls\n", command);

#if !defined(VENV_REDIRECT)
    /* bpo-35811: The __PYVENV_LAUNCHER__ variable is used to
     * override sys.executable and locate the original prefix path.
     * However, if it is silently inherited by a non-venv Python
     * process, that process will believe it is running in the venv
     * still. This is the only place where *we* can clear it (that is,
     * when py.exe is being used to launch Python), so we do.
     */
    SetEnvironmentVariableW(L"__PYVENV_LAUNCHER__", NULL);
#endif

#if defined(SCRIPT_WRAPPER)
    /* The launcher is being used in "script wrapper" mode.
     * There should therefore be a Python script named <exename>-script.py in
     * the same directory as the launcher executable.
     * Put the script name into argv as the first (script name) argument.
     */

    /* Get the wrapped script name - if the script is not present, this will
     * terminate the program with an error.
     */
    locate_wrapped_script();

    /* Add the wrapped script to the start of command */
    newlen = wcslen(wrapped_script_path) + wcslen(command) + 2; /* ' ' + NUL */
    newcommand = malloc(sizeof(wchar_t) * newlen);
    if (!newcommand) {
        error(RC_NO_MEMORY, L"Could not allocate new command line");
    }
    else {
        wcscpy_s(newcommand, newlen, wrapped_script_path);
        wcscat_s(newcommand, newlen, L" ");
        wcscat_s(newcommand, newlen, command);
        debug(L"Running wrapped script with command line '%ls'\n", newcommand);
        read_commands();
        av[0] = wrapped_script_path;
        av[1] = NULL;
        maybe_handle_shebang(av, newcommand);
        /* Returns if no shebang line - pass to default processing */
        command = newcommand;
        valid = FALSE;
    }
#elif defined(VENV_REDIRECT)
    {
        FILE *f;
        char buffer[4096]; /* 4KB should be enough for anybody */
        char *start;
        DWORD len, cch, cch_actual;
        size_t cb;
        if (_wfopen_s(&f, venv_cfg_path, L"r")) {
            error(RC_BAD_VENV_CFG, L"Cannot read '%ls'", venv_cfg_path);
        }
        cb = fread_s(buffer, sizeof(buffer), sizeof(buffer[0]),
                     sizeof(buffer) / sizeof(buffer[0]), f);
        fclose(f);

        if (!find_home_value(buffer, &start, &len)) {
            error(RC_BAD_VENV_CFG, L"Cannot find home in '%ls'",
                  venv_cfg_path);
        }

        cch = MultiByteToWideChar(CP_UTF8, 0, start, len, NULL, 0);
        if (!cch) {
            error(0, L"Cannot determine memory for home path");
        }
        cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 1 + 1; /* include sep and null */
        executable = (wchar_t *)malloc(cch * sizeof(wchar_t));
        if (executable == NULL) {
            error(RC_NO_MEMORY, L"A memory allocation failed");
        }
        cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, executable, cch);
        if (!cch_actual) {
            error(RC_BAD_VENV_CFG, L"Cannot decode home path in '%ls'",
                  venv_cfg_path);
        }
        if (executable[cch_actual - 1] != L'\\') {
            executable[cch_actual++] = L'\\';
            executable[cch_actual] = L'\0';
        }
        if (wcscat_s(executable, cch, PYTHON_EXECUTABLE)) {
            error(RC_BAD_VENV_CFG, L"Cannot create executable path from '%ls'",
                  venv_cfg_path);
        }
        if (GetFileAttributesW(executable) == INVALID_FILE_ATTRIBUTES) {
            error(RC_NO_PYTHON, L"No Python at '%ls'", executable);
        }
        if (!SetEnvironmentVariableW(L"__PYVENV_LAUNCHER__", argv0)) {
            error(0, L"Failed to set launcher environment");
        }
        valid = 1;
    }
#else
    if (argc <= 1) {
        valid = FALSE;
        p = NULL;
    }
    else {
        p = argv[1];
        if ((argc == 2) && // list version args
            (!wcsncmp(p, L"-0", wcslen(L"-0")) ||
            !wcsncmp(p, L"--list", wcslen(L"--list"))))
        {
            show_python_list(argv);
            return rc;
        }
        valid = valid && (*p == L'-') && validate_version(&p[1]);
        if (valid) {
            ip = locate_python(&p[1], FALSE);
            if (ip == NULL)
            {
                fwprintf(stdout, \
                         L"Python %ls not found!\n", &p[1]);
                valid = show_python_list(argv);
                error(RC_NO_PYTHON, L"Requested Python version (%ls) not \
installed, use -0 for available pythons", &p[1]);
            }
            executable = ip->executable;
            command += wcslen(p);
            command = skip_whitespace(command);
        }
        else {
            for (index = 1; index < argc; ++index) {
                if (*argv[index] != L'-')
                    break;
            }
            if (index < argc) {
                read_commands();
                maybe_handle_shebang(&argv[index], command);
            }
        }
    }
#endif

    if (!valid) {
        if ((argc == 2) && (!_wcsicmp(p, L"-h") || !_wcsicmp(p, L"--help")))
            show_help_text(argv);
        if ((argc == 2) &&
            (!_wcsicmp(p, L"-0") || !_wcsicmp(p, L"--list") ||
            !_wcsicmp(p, L"-0p") || !_wcsicmp(p, L"--list-paths")))
        {
            executable = NULL; /* Info call only */
        }
        else {
            /* look for the default Python */
            ip = locate_python(L"", FALSE);
            if (ip == NULL)
                error(RC_NO_PYTHON, L"Can't find a default Python.");
            executable = ip->executable;
        }
    }
    if (executable != NULL)
        invoke_child(executable, NULL, command);
    else
        rc = RC_NO_PYTHON;
    return rc;
}

#if defined(_WINDOWS)

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPWSTR lpstrCmd, int nShow)
{
    return process(__argc, __wargv);
}

#else

int cdecl wmain(int argc, wchar_t ** argv)
{
    return process(argc, argv);
}

#endif
