/*
 * Rewritten Python launcher for Windows
 *
 * This new rewrite properly handles PEP 514 and allows any registered Python
 * runtime to be launched. It also enables auto-install of versions when they
 * are requested but no installation can be found.
 */

#define __STDC_WANT_LIB_EXT1__ 1

#include <windows.h>
#include <pathcch.h>
#include <fcntl.h>
#include <io.h>
#include <shlobj.h>
#include <stdio.h>
#include <stdbool.h>
#include <tchar.h>
#include <assert.h>

#define MS_WINDOWS
#include "patchlevel.h"

#define MAXLEN PATHCCH_MAX_CCH
#define MSGSIZE 1024

#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
#define RC_NO_SCRIPT        105
#define RC_NO_VENV_CFG      106
#define RC_BAD_VENV_CFG     107
#define RC_NO_COMMANDLINE   108
#define RC_INTERNAL_ERROR   109
#define RC_DUPLICATE_ITEM   110
#define RC_INSTALLING       111
#define RC_NO_PYTHON_AT_ALL 112
#define RC_NO_SHEBANG       113
#define RC_RECURSIVE_SHEBANG 114

static FILE * log_fp = NULL;

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

    if (log_fp != NULL) {
        wchar_t buffer[MAXLEN];
        int r = 0;
        va_start(va, format);
        r = vswprintf_s(buffer, MAXLEN, format, va);
        va_end(va);

        if (r <= 0) {
            return;
        }
        fputws(buffer, log_fp);
        while (r && isspace(buffer[r])) {
            buffer[r--] = L'\0';
        }
        if (buffer[0]) {
            OutputDebugStringW(buffer);
        }
    }
}


void
formatWinerror(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);
}


void
winerror(int err, wchar_t * format, ... )
{
    va_list va;
    wchar_t message[MSGSIZE];
    wchar_t win_message[MSGSIZE];
    int len;

    if (err == 0) {
        err = GetLastError();
    }

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

    formatWinerror(err, win_message, MSGSIZE);
    if (len >= 0) {
        _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %s",
                     win_message);
    }

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


void
error(wchar_t * format, ... )
{
    va_list va;
    wchar_t message[MSGSIZE];

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

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


typedef BOOL (*PIsWow64Process2)(HANDLE, USHORT*, USHORT*);


USHORT
_getNativeMachine(void)
{
    static USHORT _nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN;
    if (_nativeMachine == IMAGE_FILE_MACHINE_UNKNOWN) {
        USHORT processMachine;
        HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
        PIsWow64Process2 IsWow64Process2 = kernel32 ?
            (PIsWow64Process2)GetProcAddress(kernel32, "IsWow64Process2") :
            NULL;
        if (!IsWow64Process2) {
            BOOL wow64Process;
            if (!IsWow64Process(NULL, &wow64Process)) {
                winerror(0, L"Checking process type");
            } else if (wow64Process) {
                // We should always be a 32-bit executable, so if running
                // under emulation, it must be a 64-bit host.
                _nativeMachine = IMAGE_FILE_MACHINE_AMD64;
            } else {
                // Not running under emulation, and an old enough OS to not
                // have IsWow64Process2, so assume it's x86.
                _nativeMachine = IMAGE_FILE_MACHINE_I386;
            }
        } else if (!IsWow64Process2(NULL, &processMachine, &_nativeMachine)) {
            winerror(0, L"Checking process type");
        }
    }
    return _nativeMachine;
}


bool
isAMD64Host(void)
{
    return _getNativeMachine() == IMAGE_FILE_MACHINE_AMD64;
}


bool
isARM64Host(void)
{
    return _getNativeMachine() == IMAGE_FILE_MACHINE_ARM64;
}


bool
isEnvVarSet(const wchar_t *name)
{
    /* only looking for non-empty, which means at least one character
       and the null terminator */
    return GetEnvironmentVariableW(name, NULL, 0) >= 2;
}


bool
join(wchar_t *buffer, size_t bufferLength, const wchar_t *fragment)
{
    if (SUCCEEDED(PathCchCombineEx(buffer, bufferLength, buffer, fragment, PATHCCH_ALLOW_LONG_PATHS))) {
        return true;
    }
    return false;
}


bool
split_parent(wchar_t *buffer, size_t bufferLength)
{
    return SUCCEEDED(PathCchRemoveFileSpec(buffer, bufferLength));
}


int
_compare(const wchar_t *x, int xLen, const wchar_t *y, int yLen)
{
    // Empty strings sort first
    if (!x || !xLen) {
        return (!y || !yLen) ? 0 : -1;
    } else if (!y || !yLen) {
        return 1;
    }
    switch (CompareStringEx(
        LOCALE_NAME_INVARIANT, NORM_IGNORECASE | SORT_DIGITSASNUMBERS,
        x, xLen, y, yLen,
        NULL, NULL, 0
    )) {
    case CSTR_LESS_THAN:
        return -1;
    case CSTR_EQUAL:
        return 0;
    case CSTR_GREATER_THAN:
        return 1;
    default:
        winerror(0, L"Error comparing '%.*s' and '%.*s' (compare)", xLen, x, yLen, y);
        return -1;
    }
}


int
_compareArgument(const wchar_t *x, int xLen, const wchar_t *y, int yLen)
{
    // Empty strings sort first
    if (!x || !xLen) {
        return (!y || !yLen) ? 0 : -1;
    } else if (!y || !yLen) {
        return 1;
    }
    switch (CompareStringEx(
        LOCALE_NAME_INVARIANT, 0,
        x, xLen, y, yLen,
        NULL, NULL, 0
    )) {
    case CSTR_LESS_THAN:
        return -1;
    case CSTR_EQUAL:
        return 0;
    case CSTR_GREATER_THAN:
        return 1;
    default:
        winerror(0, L"Error comparing '%.*s' and '%.*s' (compareArgument)", xLen, x, yLen, y);
        return -1;
    }
}

int
_comparePath(const wchar_t *x, int xLen, const wchar_t *y, int yLen)
{
    // Empty strings sort first
    if (!x || !xLen) {
        return !y || !yLen ? 0 : -1;
    } else if (!y || !yLen) {
        return 1;
    }
    switch (CompareStringOrdinal(x, xLen, y, yLen, TRUE)) {
    case CSTR_LESS_THAN:
        return -1;
    case CSTR_EQUAL:
        return 0;
    case CSTR_GREATER_THAN:
        return 1;
    default:
        winerror(0, L"Error comparing '%.*s' and '%.*s' (comparePath)", xLen, x, yLen, y);
        return -1;
    }
}


bool
_startsWith(const wchar_t *x, int xLen, const wchar_t *y, int yLen)
{
    if (!x || !y) {
        return false;
    }
    yLen = yLen < 0 ? (int)wcsnlen_s(y, MAXLEN) : yLen;
    xLen = xLen < 0 ? (int)wcsnlen_s(x, MAXLEN) : xLen;
    return xLen >= yLen && 0 == _compare(x, yLen, y, yLen);
}


bool
_startsWithArgument(const wchar_t *x, int xLen, const wchar_t *y, int yLen)
{
    if (!x || !y) {
        return false;
    }
    yLen = yLen < 0 ? (int)wcsnlen_s(y, MAXLEN) : yLen;
    xLen = xLen < 0 ? (int)wcsnlen_s(x, MAXLEN) : xLen;
    return xLen >= yLen && 0 == _compareArgument(x, yLen, y, yLen);
}


// Unlike regular startsWith, this function requires that the following
// character is either NULL (that is, the entire string matches) or is one of
// the characters in 'separators'.
bool
_startsWithSeparated(const wchar_t *x, int xLen, const wchar_t *y, int yLen, const wchar_t *separators)
{
    if (!x || !y) {
        return false;
    }
    yLen = yLen < 0 ? (int)wcsnlen_s(y, MAXLEN) : yLen;
    xLen = xLen < 0 ? (int)wcsnlen_s(x, MAXLEN) : xLen;
    if (xLen < yLen) {
        return false;
    }
    if (xLen == yLen) {
        return 0 == _compare(x, xLen, y, yLen);
    }
    return separators &&
        0 == _compare(x, yLen, y, yLen) &&
        wcschr(separators, x[yLen]) != NULL;
}



/******************************************************************************\
 ***                               HELP TEXT                                ***
\******************************************************************************/


int
showHelpText(wchar_t ** argv)
{
    // The help text is stored in launcher-usage.txt, which is compiled into
    // the launcher and loaded at runtime if needed.
    //
    // The file must be UTF-8. There are two substitutions:
    //  %ls - PY_VERSION (as wchar_t*)
    //  %ls - argv[0] (as wchar_t*)
    HRSRC res = FindResourceExW(NULL, L"USAGE", MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
    HGLOBAL resData = res ? LoadResource(NULL, res) : NULL;
    const char *usage = resData ? (const char*)LockResource(resData) : NULL;
    if (usage == NULL) {
        winerror(0, L"Unable to load usage text");
        return RC_INTERNAL_ERROR;
    }

    DWORD cbData = SizeofResource(NULL, res);
    DWORD cchUsage = MultiByteToWideChar(CP_UTF8, 0, usage, cbData, NULL, 0);
    if (!cchUsage) {
        winerror(0, L"Unable to preprocess usage text");
        return RC_INTERNAL_ERROR;
    }

    cchUsage += 1;
    wchar_t *wUsage = (wchar_t*)malloc(cchUsage * sizeof(wchar_t));
    cchUsage = MultiByteToWideChar(CP_UTF8, 0, usage, cbData, wUsage, cchUsage);
    if (!cchUsage) {
        winerror(0, L"Unable to preprocess usage text");
        free((void *)wUsage);
        return RC_INTERNAL_ERROR;
    }
    // Ensure null termination
    wUsage[cchUsage] = L'\0';

    fwprintf(stdout, wUsage, (L"" PY_VERSION), argv[0]);
    fflush(stdout);

    free((void *)wUsage);

    return 0;
}


/******************************************************************************\
 ***                              SEARCH INFO                               ***
\******************************************************************************/


struct _SearchInfoBuffer {
    struct _SearchInfoBuffer *next;
    wchar_t buffer[0];
};


typedef struct {
    // the original string, managed by the OS
    const wchar_t *originalCmdLine;
    // pointer into the cmdline to mark what we've consumed
    const wchar_t *restOfCmdLine;
    // if known/discovered, the full executable path of our runtime
    const wchar_t *executablePath;
    // pointer and length into cmdline for the file to check for a
    // shebang line, if any. Length can be -1 if the string is null
    // terminated.
    const wchar_t *scriptFile;
    int scriptFileLength;
    // pointer and length into cmdline or a static string with the
    // name of the target executable. Length can be -1 if the string
    // is null terminated.
    const wchar_t *executable;
    int executableLength;
    // pointer and length into a string with additional interpreter
    // arguments to include before restOfCmdLine. Length can be -1 if
    // the string is null terminated.
    const wchar_t *executableArgs;
    int executableArgsLength;
    // pointer and length into cmdline or a static string with the
    // company name for PEP 514 lookup. Length can be -1 if the string
    // is null terminated.
    const wchar_t *company;
    int companyLength;
    // pointer and length into cmdline or a static string with the
    // tag for PEP 514 lookup. Length can be -1 if the string is
    // null terminated.
    const wchar_t *tag;
    int tagLength;
    // if true, treats 'tag' as a non-PEP 514 filter
    bool oldStyleTag;
    // if true, ignores 'tag' when a high priority environment is found
    // gh-92817: This is currently set when a tag is read from configuration,
    // the environment, or a shebang, rather than the command line, and the
    // only currently possible high priority environment is an active virtual
    // environment
    bool lowPriorityTag;
    // if true, allow PEP 514 lookup to override 'executable'
    bool allowExecutableOverride;
    // if true, allow a nearby pyvenv.cfg to locate the executable
    bool allowPyvenvCfg;
    // if true, allow defaults (env/py.ini) to clarify/override tags
    bool allowDefaults;
    // if true, prefer windowed (console-less) executable
    bool windowed;
    // if true, only list detected runtimes without launching
    bool list;
    // if true, only list detected runtimes with paths without launching
    bool listPaths;
    // if true, display help message before continuing
    bool help;
    // if set, limits search to registry keys with the specified Company
    // This is intended for debugging and testing only
    const wchar_t *limitToCompany;
    // dynamically allocated buffers to free later
    struct _SearchInfoBuffer *_buffer;
} SearchInfo;


wchar_t *
allocSearchInfoBuffer(SearchInfo *search, int wcharCount)
{
    struct _SearchInfoBuffer *buffer = (struct _SearchInfoBuffer*)malloc(
        sizeof(struct _SearchInfoBuffer) +
        wcharCount * sizeof(wchar_t)
    );
    if (!buffer) {
        return NULL;
    }
    buffer->next = search->_buffer;
    search->_buffer = buffer;
    return buffer->buffer;
}


void
freeSearchInfo(SearchInfo *search)
{
    struct _SearchInfoBuffer *b = search->_buffer;
    search->_buffer = NULL;
    while (b) {
        struct _SearchInfoBuffer *nextB = b->next;
        free((void *)b);
        b = nextB;
    }
}


void
_debugStringAndLength(const wchar_t *s, int len, const wchar_t *name)
{
    if (!s) {
        debug(L"%s: (null)\n", name);
    } else if (len == 0) {
        debug(L"%s: (empty)\n", name);
    } else if (len < 0) {
        debug(L"%s: %s\n", name, s);
    } else {
        debug(L"%s: %.*ls\n", name, len, s);
    }
}


void
dumpSearchInfo(SearchInfo *search)
{
    if (!log_fp) {
        return;
    }

#ifdef __clang__
#define DEBUGNAME(s) L # s
#else
#define DEBUGNAME(s) # s
#endif
#define DEBUG(s) debug(L"SearchInfo." DEBUGNAME(s) L": %s\n", (search->s) ? (search->s) : L"(null)")
#define DEBUG_2(s, sl) _debugStringAndLength((search->s), (search->sl), L"SearchInfo." DEBUGNAME(s))
#define DEBUG_BOOL(s) debug(L"SearchInfo." DEBUGNAME(s) L": %s\n", (search->s) ? L"True" : L"False")
    DEBUG(originalCmdLine);
    DEBUG(restOfCmdLine);
    DEBUG(executablePath);
    DEBUG_2(scriptFile, scriptFileLength);
    DEBUG_2(executable, executableLength);
    DEBUG_2(executableArgs, executableArgsLength);
    DEBUG_2(company, companyLength);
    DEBUG_2(tag, tagLength);
    DEBUG_BOOL(oldStyleTag);
    DEBUG_BOOL(lowPriorityTag);
    DEBUG_BOOL(allowDefaults);
    DEBUG_BOOL(allowExecutableOverride);
    DEBUG_BOOL(windowed);
    DEBUG_BOOL(list);
    DEBUG_BOOL(listPaths);
    DEBUG_BOOL(help);
    DEBUG(limitToCompany);
#undef DEBUG_BOOL
#undef DEBUG_2
#undef DEBUG
#undef DEBUGNAME
}


int
findArgv0Length(const wchar_t *buffer, int bufferLength)
{
    // Note: this implements semantics that are only valid for argv0.
    // Specifically, there is no escaping of quotes, and quotes within
    // the argument have no effect. A quoted argv0 must start and end
    // with a double quote character; otherwise, it ends at the first
    // ' ' or '\t'.
    int quoted = buffer[0] == L'"';
    for (int i = 1; bufferLength < 0 || i < bufferLength; ++i) {
        switch (buffer[i]) {
        case L'\0':
            return i;
        case L' ':
        case L'\t':
            if (!quoted) {
                return i;
            }
            break;
        case L'"':
            if (quoted) {
                return i + 1;
            }
            break;
        }
    }
    return bufferLength;
}


const wchar_t *
findArgv0End(const wchar_t *buffer, int bufferLength)
{
    return &buffer[findArgv0Length(buffer, bufferLength)];
}


/******************************************************************************\
 ***                          COMMAND-LINE PARSING                          ***
\******************************************************************************/

// Adapted from https://stackoverflow.com/a/65583702
typedef struct AppExecLinkFile { // For tag IO_REPARSE_TAG_APPEXECLINK
    DWORD reparseTag;
    WORD reparseDataLength;
    WORD reserved;
    ULONG version;
    wchar_t stringList[MAX_PATH * 4];  // Multistring (Consecutive UTF-16 strings each ending with a NUL)
    /* There are normally 4 strings here. Ex:
        Package ID:  L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
        Entry Point: L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe!PythonRedirector"
        Executable:  L"C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.17.106910_x64__8wekyb3d8bbwe\AppInstallerPythonRedirector.exe"
        Applic. Type: L"0"   // Integer as ASCII. "0" = Desktop bridge application; Else sandboxed UWP application
    */
} AppExecLinkFile;


int
parseCommandLine(SearchInfo *search)
{
    if (!search || !search->originalCmdLine) {
        return RC_NO_COMMANDLINE;
    }

    const wchar_t *argv0End = findArgv0End(search->originalCmdLine, -1);
    const wchar_t *tail = argv0End; // will be start of the executable name
    const wchar_t *end = argv0End;  // will be end of the executable name
    search->restOfCmdLine = argv0End;   // will be first space after argv0
    while (--tail != search->originalCmdLine) {
        if (*tail == L'"' && end == argv0End) {
            // Move the "end" up to the quote, so we also allow moving for
            // a period later on.
            end = argv0End = tail;
        } else if (*tail == L'.' && end == argv0End) {
            end = tail;
        } else if (*tail == L'\\' || *tail == L'/') {
            ++tail;
            break;
        }
    }
    if (tail == search->originalCmdLine && tail[0] == L'"') {
        ++tail;
    }
    // Without special cases, we can now fill in the search struct
    int tailLen = (int)(end ? (end - tail) : wcsnlen_s(tail, MAXLEN));
    search->executableLength = -1;

    // Our special cases are as follows
#define MATCHES(s) (0 == _comparePath(tail, tailLen, (s), -1))
#define STARTSWITH(s) _startsWith(tail, tailLen, (s), -1)
    if (MATCHES(L"py")) {
        search->executable = L"python.exe";
        search->allowExecutableOverride = true;
        search->allowDefaults = true;
    } else if (MATCHES(L"pyw")) {
        search->executable = L"pythonw.exe";
        search->allowExecutableOverride = true;
        search->allowDefaults = true;
        search->windowed = true;
    } else if (MATCHES(L"py_d")) {
        search->executable = L"python_d.exe";
        search->allowExecutableOverride = true;
        search->allowDefaults = true;
    } else if (MATCHES(L"pyw_d")) {
        search->executable = L"pythonw_d.exe";
        search->allowExecutableOverride = true;
        search->allowDefaults = true;
        search->windowed = true;
    } else if (STARTSWITH(L"python3")) {
        search->executable = L"python.exe";
        search->tag = &tail[6];
        search->tagLength = tailLen - 6;
        search->allowExecutableOverride = true;
        search->oldStyleTag = true;
        search->allowPyvenvCfg = true;
    } else if (STARTSWITH(L"pythonw3")) {
        search->executable = L"pythonw.exe";
        search->tag = &tail[7];
        search->tagLength = tailLen - 7;
        search->allowExecutableOverride = true;
        search->oldStyleTag = true;
        search->allowPyvenvCfg = true;
        search->windowed = true;
    } else {
        search->executable = tail;
        search->executableLength = tailLen;
        search->allowPyvenvCfg = true;
    }
#undef STARTSWITH
#undef MATCHES

    // First argument might be one of our options. If so, consume it,
    // update flags and then set restOfCmdLine.
    const wchar_t *arg = search->restOfCmdLine;
    while(*arg && isspace(*arg)) { ++arg; }
#define MATCHES(s) (0 == _compareArgument(arg, argLen, (s), -1))
#define STARTSWITH(s) _startsWithArgument(arg, argLen, (s), -1)
    if (*arg && *arg == L'-' && *++arg) {
        tail = arg;
        while (*tail && !isspace(*tail)) { ++tail; }
        int argLen = (int)(tail - arg);
        if (argLen > 0) {
            if (STARTSWITH(L"2") || STARTSWITH(L"3")) {
                // All arguments starting with 2 or 3 are assumed to be version tags
                search->tag = arg;
                search->tagLength = argLen;
                search->oldStyleTag = true;
                search->restOfCmdLine = tail;
            } else if (STARTSWITH(L"V:") || STARTSWITH(L"-version:")) {
                // Arguments starting with 'V:' specify company and/or tag
                const wchar_t *argStart = wcschr(arg, L':') + 1;
                const wchar_t *tagStart = wcschr(argStart, L'/') ;
                if (tagStart) {
                    search->company = argStart;
                    search->companyLength = (int)(tagStart - argStart);
                    search->tag = tagStart + 1;
                } else {
                    search->tag = argStart;
                }
                search->tagLength = (int)(tail - search->tag);
                search->allowDefaults = false;
                search->restOfCmdLine = tail;
            } else if (MATCHES(L"0") || MATCHES(L"-list")) {
                search->list = true;
                search->restOfCmdLine = tail;
            } else if (MATCHES(L"0p") || MATCHES(L"-list-paths")) {
                search->listPaths = true;
                search->restOfCmdLine = tail;
            } else if (MATCHES(L"h") || MATCHES(L"-help")) {
                search->help = true;
                // Do not update restOfCmdLine so that we trigger the help
                // message from whichever interpreter we select
            }
        }
    }
#undef STARTSWITH
#undef MATCHES

    // Might have a script filename. If it looks like a filename, add
    // it to the SearchInfo struct for later reference.
    arg = search->restOfCmdLine;
    while(*arg && isspace(*arg)) { ++arg; }
    if (*arg && *arg != L'-') {
        search->scriptFile = arg;
        if (*arg == L'"') {
            ++search->scriptFile;
            while (*++arg && *arg != L'"') { }
        } else {
            while (*arg && !isspace(*arg)) { ++arg; }
        }
        search->scriptFileLength = (int)(arg - search->scriptFile);
    }

    return 0;
}


int
_decodeShebang(SearchInfo *search, const char *buffer, int bufferLength, bool onlyUtf8, wchar_t **decoded, int *decodedLength)
{
    DWORD cp = CP_UTF8;
    int wideLen = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buffer, bufferLength, NULL, 0);
    if (!wideLen) {
        cp = CP_ACP;
        wideLen = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buffer, bufferLength, NULL, 0);
        if (!wideLen) {
            debug(L"# Failed to decode shebang line (0x%08X)\n", GetLastError());
            return RC_BAD_VIRTUAL_PATH;
        }
    }
    wchar_t *b = allocSearchInfoBuffer(search, wideLen + 1);
    if (!b) {
        return RC_NO_MEMORY;
    }
    wideLen = MultiByteToWideChar(cp, 0, buffer, bufferLength, b, wideLen + 1);
    if (!wideLen) {
        debug(L"# Failed to decode shebang line (0x%08X)\n", GetLastError());
        return RC_BAD_VIRTUAL_PATH;
    }
    b[wideLen] = L'\0';
    *decoded = b;
    *decodedLength = wideLen;
    return 0;
}


bool
_shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefix, const wchar_t **rest, int *firstArgumentLength)
{
    int prefixLength = (int)wcsnlen_s(prefix, MAXLEN);
    if (bufferLength < prefixLength || !_startsWithArgument(buffer, bufferLength, prefix, prefixLength)) {
        return false;
    }
    if (rest) {
        *rest = &buffer[prefixLength];
    }
    if (firstArgumentLength) {
        int i = prefixLength;
        while (i < bufferLength && !isspace(buffer[i])) {
            i += 1;
        }
        *firstArgumentLength = i - prefixLength;
    }
    return true;
}


int
ensure_no_redirector_stub(wchar_t* filename, wchar_t* buffer)
{
    // Make sure we didn't find a reparse point that will open the Microsoft Store
    // If we did, pretend there was no shebang and let normal handling take over
    WIN32_FIND_DATAW findData;
    HANDLE hFind = FindFirstFileW(buffer, &findData);
    if (!hFind) {
        // Let normal handling take over
        debug(L"# Did not find %s on PATH\n", filename);
        return RC_NO_SHEBANG;
    }

    FindClose(hFind);

    if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
        findData.dwReserved0 & IO_REPARSE_TAG_APPEXECLINK)) {
        return 0;
    }

    HANDLE hReparsePoint = CreateFileW(buffer, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL);
    if (!hReparsePoint) {
        // Let normal handling take over
        debug(L"# Did not find %s on PATH\n", filename);
        return RC_NO_SHEBANG;
    }

    AppExecLinkFile appExecLink;

    if (!DeviceIoControl(hReparsePoint, FSCTL_GET_REPARSE_POINT, NULL, 0, &appExecLink, sizeof(appExecLink), NULL, NULL)) {
        // Let normal handling take over
        debug(L"# Did not find %s on PATH\n", filename);
        CloseHandle(hReparsePoint);
        return RC_NO_SHEBANG;
    }

    CloseHandle(hReparsePoint);

    const wchar_t* redirectorPackageId = L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe";

    if (0 == wcscmp(appExecLink.stringList, redirectorPackageId)) {
        debug(L"# ignoring redirector that would launch store\n");
        return RC_NO_SHEBANG;
    }

    return 0;
}


int
searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength)
{
    if (isEnvVarSet(L"PYLAUNCHER_NO_SEARCH_PATH")) {
        return RC_NO_SHEBANG;
    }

    wchar_t *command;
    int commandLength;
    if (!_shebangStartsWith(shebang, shebangLength, L"/usr/bin/env ", &command, &commandLength)) {
        return RC_NO_SHEBANG;
    }

    if (!commandLength || commandLength == MAXLEN) {
        return RC_BAD_VIRTUAL_PATH;
    }

    int lastDot = commandLength;
    while (lastDot > 0 && command[lastDot] != L'.') {
        lastDot -= 1;
    }
    if (!lastDot) {
        lastDot = commandLength;
    }

    wchar_t filename[MAXLEN];
    if (wcsncpy_s(filename, MAXLEN, command, commandLength)) {
        return RC_BAD_VIRTUAL_PATH;
    }

    const wchar_t *ext = L".exe";
    // If the command already has an extension, we do not want to add it again
    if (!lastDot || _comparePath(&filename[lastDot], -1, ext, -1)) {
        if (wcscat_s(filename, MAXLEN, L".exe")) {
            return RC_BAD_VIRTUAL_PATH;
        }
    }

    debug(L"# Search PATH for %s\n", filename);

    wchar_t pathVariable[MAXLEN];
    int n = GetEnvironmentVariableW(L"PATH", pathVariable, MAXLEN);
    if (!n) {
        if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
            return RC_NO_SHEBANG;
        }
        winerror(0, L"Failed to read PATH\n", filename);
        return RC_INTERNAL_ERROR;
    }

    wchar_t buffer[MAXLEN];
    n = SearchPathW(pathVariable, filename, NULL, MAXLEN, buffer, NULL);
    if (!n) {
        if (GetLastError() == ERROR_FILE_NOT_FOUND) {
            debug(L"# Did not find %s on PATH\n", filename);
            // If we didn't find it on PATH, let normal handling take over
            return RC_NO_SHEBANG;
        }
        // Other errors should cause us to break
        winerror(0, L"Failed to find %s on PATH\n", filename);
        return RC_BAD_VIRTUAL_PATH;
    }

    int result = ensure_no_redirector_stub(filename, buffer);
    if (result) {
        return result;
    }

    // Check that we aren't going to call ourselves again
    // If we are, pretend there was no shebang and let normal handling take over
    if (GetModuleFileNameW(NULL, filename, MAXLEN) &&
        0 == _comparePath(filename, -1, buffer, -1)) {
        debug(L"# ignoring recursive shebang command\n");
        return RC_RECURSIVE_SHEBANG;
    }

    wchar_t *buf = allocSearchInfoBuffer(search, n + 1);
    if (!buf || wcscpy_s(buf, n + 1, buffer)) {
        return RC_NO_MEMORY;
    }

    search->executablePath = buf;
    search->executableArgs = &command[commandLength];
    search->executableArgsLength = shebangLength - commandLength;
    debug(L"# Found %s on PATH\n", buf);

    return 0;
}


int
_readIni(const wchar_t *section, const wchar_t *settingName, wchar_t *buffer, int bufferLength)
{
    wchar_t iniPath[MAXLEN];
    int n;
    if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, iniPath)) &&
        join(iniPath, MAXLEN, L"py.ini")) {
        debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName);
        n = GetPrivateProfileStringW(section, settingName, NULL, buffer, bufferLength, iniPath);
        if (n) {
            debug(L"# Found %s in %s\n", settingName, iniPath);
            return n;
        } else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
            debug(L"# Did not find file %s\n", iniPath);
        } else {
            winerror(0, L"Failed to read from %s\n", iniPath);
        }
    }
    if (GetModuleFileNameW(NULL, iniPath, MAXLEN) &&
        SUCCEEDED(PathCchRemoveFileSpec(iniPath, MAXLEN)) &&
        join(iniPath, MAXLEN, L"py.ini")) {
        debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName);
        n = GetPrivateProfileStringW(section, settingName, NULL, buffer, MAXLEN, iniPath);
        if (n) {
            debug(L"# Found %s in %s\n", settingName, iniPath);
            return n;
        } else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
            debug(L"# Did not find file %s\n", iniPath);
        } else {
            winerror(0, L"Failed to read from %s\n", iniPath);
        }
    }
    return 0;
}


bool
_findCommand(SearchInfo *search, const wchar_t *command, int commandLength)
{
    wchar_t commandBuffer[MAXLEN];
    wchar_t buffer[MAXLEN];
    wcsncpy_s(commandBuffer, MAXLEN, command, commandLength);
    int n = _readIni(L"commands", commandBuffer, buffer, MAXLEN);
    if (!n) {
        return false;
    }
    wchar_t *path = allocSearchInfoBuffer(search, n + 1);
    if (!path) {
        return false;
    }
    wcscpy_s(path, n + 1, buffer);
    search->executablePath = path;
    return true;
}


int
_useShebangAsExecutable(SearchInfo *search, const wchar_t *shebang, int shebangLength)
{
    wchar_t buffer[MAXLEN];
    wchar_t script[MAXLEN];
    wchar_t command[MAXLEN];

    int commandLength = 0;
    int inQuote = 0;

    if (!shebang || !shebangLength) {
        return 0;
    }

    wchar_t *pC = command;
    for (int i = 0; i < shebangLength; ++i) {
        wchar_t c = shebang[i];
        if (isspace(c) && !inQuote) {
            commandLength = i;
            break;
        } else if (c == L'"') {
            inQuote = !inQuote;
        } else if (c == L'/' || c == L'\\') {
            *pC++ = L'\\';
        } else {
            *pC++ = c;
        }
    }
    *pC = L'\0';

    if (!GetCurrentDirectoryW(MAXLEN, buffer) ||
        wcsncpy_s(script, MAXLEN, search->scriptFile, search->scriptFileLength) ||
        FAILED(PathCchCombineEx(buffer, MAXLEN, buffer, script,
                                PATHCCH_ALLOW_LONG_PATHS)) ||
        FAILED(PathCchRemoveFileSpec(buffer, MAXLEN)) ||
        FAILED(PathCchCombineEx(buffer, MAXLEN, buffer, command,
                                PATHCCH_ALLOW_LONG_PATHS))
    ) {
        return RC_NO_MEMORY;
    }

    int n = (int)wcsnlen(buffer, MAXLEN);
    wchar_t *path = allocSearchInfoBuffer(search, n + 1);
    if (!path) {
        return RC_NO_MEMORY;
    }
    wcscpy_s(path, n + 1, buffer);
    search->executablePath = path;
    if (commandLength) {
        search->executableArgs = &shebang[commandLength];
        search->executableArgsLength = shebangLength - commandLength;
    }
    return 0;
}


int
checkShebang(SearchInfo *search)
{
    // Do not check shebang if a tag was provided or if no script file
    // was found on the command line.
    if (search->tag || !search->scriptFile) {
        return 0;
    }

    if (search->scriptFileLength < 0) {
        search->scriptFileLength = (int)wcsnlen_s(search->scriptFile, MAXLEN);
    }

    wchar_t *scriptFile = (wchar_t*)malloc(sizeof(wchar_t) * (search->scriptFileLength + 1));
    if (!scriptFile) {
        return RC_NO_MEMORY;
    }

    wcsncpy_s(scriptFile, search->scriptFileLength + 1,
              search->scriptFile, search->scriptFileLength);

    HANDLE hFile = CreateFileW(scriptFile, GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL, OPEN_EXISTING, 0, NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        debug(L"# Failed to open %s for shebang parsing (0x%08X)\n",
              scriptFile, GetLastError());
        free(scriptFile);
        return 0;
    }

    DWORD bytesRead = 0;
    unsigned char buffer[4096];
    if (!ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL)) {
        debug(L"# Failed to read %s for shebang parsing (0x%08X)\n",
              scriptFile, GetLastError());
        free(scriptFile);
        return 0;
    }

    CloseHandle(hFile);
    debug(L"# Read %d bytes from %s to find shebang line\n", bytesRead, scriptFile);
    free(scriptFile);


    unsigned char *b = buffer;
    bool onlyUtf8 = false;
    if (bytesRead > 3 && *b == 0xEF) {
        if (*++b == 0xBB && *++b == 0xBF) {
            // Allow a UTF-8 BOM
            ++b;
            bytesRead -= 3;
            onlyUtf8 = true;
        } else {
            debug(L"# Invalid BOM in shebang line");
            return 0;
        }
    }
    if (bytesRead <= 2 || b[0] != '#' || b[1] != '!') {
        // No shebang (#!) at start of line
        debug(L"# No valid shebang line");
        return 0;
    }
    ++b;
    --bytesRead;
    while (--bytesRead > 0 && isspace(*++b)) { }
    const unsigned char *start = b;
    while (--bytesRead > 0 && *++b != '\r' && *b != '\n') { }
    wchar_t *shebang;
    int shebangLength;
    // We add 1 when bytesRead==0, as in that case we hit EOF and b points
    // to the last character in the file, not the newline
    int exitCode = _decodeShebang(search, (const char*)start, (int)(b - start + (bytesRead == 0)), onlyUtf8, &shebang, &shebangLength);
    if (exitCode) {
        return exitCode;
    }
    debug(L"Shebang: %s\n", shebang);

    // Handle shebangs that we should search PATH for
    int executablePathWasSetByUsrBinEnv = 0;
    exitCode = searchPath(search, shebang, shebangLength);
    if (exitCode == 0) {
        executablePathWasSetByUsrBinEnv = 1;
    } else if (exitCode != RC_NO_SHEBANG) {
        return exitCode;
    }

    // Handle some known, case-sensitive shebangs
    const wchar_t *command;
    int commandLength;
    // Each template must end with "python"
    static const wchar_t *shebangTemplates[] = {
        L"/usr/bin/env python",
        L"/usr/bin/python",
        L"/usr/local/bin/python",
        L"python",
        NULL
    };

    for (const wchar_t **tmpl = shebangTemplates; *tmpl; ++tmpl) {
        // Just to make sure we don't mess this up in the future
        assert(0 == wcscmp(L"python", (*tmpl) + wcslen(*tmpl) - 6));

        if (_shebangStartsWith(shebang, shebangLength, *tmpl, &command, &commandLength)) {
            // Search for "python{command}" overrides. All templates end with
            // "python", so we prepend it by jumping back 6 characters
            if (_findCommand(search, &command[-6], commandLength + 6)) {
                search->executableArgs = &command[commandLength];
                search->executableArgsLength = shebangLength - commandLength;
                debug(L"# Treating shebang command '%.*s' as %s\n",
                    commandLength + 6, &command[-6], search->executablePath);
                return 0;
            }

            search->tag = command;
            search->tagLength = commandLength;
            // If we had 'python3.12.exe' then we want to strip the suffix
            // off of the tag
            if (search->tagLength >= 4) {
                const wchar_t *suffix = &search->tag[search->tagLength - 4];
                if (0 == _comparePath(suffix, 4, L".exe", -1)) {
                    search->tagLength -= 4;
                }
            }
            // If we had 'python3_d' then we want to strip the '_d' (any
            // '.exe' is already gone)
            if (search->tagLength >= 2) {
                const wchar_t *suffix = &search->tag[search->tagLength - 2];
                if (0 == _comparePath(suffix, 2, L"_d", -1)) {
                    search->tagLength -= 2;
                }
            }
            search->oldStyleTag = true;
            search->lowPriorityTag = true;
            search->executableArgs = &command[commandLength];
            search->executableArgsLength = shebangLength - commandLength;
            if (search->tag && search->tagLength) {
                debug(L"# Treating shebang command '%.*s' as 'py -%.*s'\n",
                    commandLength, command, search->tagLength, search->tag);
            } else {
                debug(L"# Treating shebang command '%.*s' as 'py'\n",
                    commandLength, command);
            }
            return 0;
        }
    }

    // Didn't match a template, but we found it on PATH
    if (executablePathWasSetByUsrBinEnv) {
        return 0;
    }

    // Unrecognised executables are first tried as command aliases
    commandLength = 0;
    while (commandLength < shebangLength && !isspace(shebang[commandLength])) {
        commandLength += 1;
    }
    if (_findCommand(search, shebang, commandLength)) {
        search->executableArgs = &shebang[commandLength];
        search->executableArgsLength = shebangLength - commandLength;
        debug(L"# Treating shebang command '%.*s' as %s\n",
            commandLength, shebang, search->executablePath);
        return 0;
    }

    // Unrecognised commands are joined to the script's directory and treated
    // as the executable path
    return _useShebangAsExecutable(search, shebang, shebangLength);
}


int
checkDefaults(SearchInfo *search)
{
    if (!search->allowDefaults) {
        return 0;
    }

    // Only resolve old-style (or absent) tags to defaults
    if (search->tag && search->tagLength && !search->oldStyleTag) {
        return 0;
    }

    // If tag is only a major version number, expand it from the environment
    // or an ini file
    const wchar_t *iniSettingName = NULL;
    const wchar_t *envSettingName = NULL;
    if (!search->tag || !search->tagLength) {
        iniSettingName = L"python";
        envSettingName = L"py_python";
    } else if (0 == wcsncmp(search->tag, L"3", search->tagLength)) {
        iniSettingName = L"python3";
        envSettingName = L"py_python3";
    } else if (0 == wcsncmp(search->tag, L"2", search->tagLength)) {
        iniSettingName = L"python2";
        envSettingName = L"py_python2";
    } else {
        debug(L"# Cannot select defaults for tag '%.*s'\n", search->tagLength, search->tag);
        return 0;
    }

    // First, try to read an environment variable
    wchar_t buffer[MAXLEN];
    int n = GetEnvironmentVariableW(envSettingName, buffer, MAXLEN);

    // If none found, check in our two .ini files instead
    if (!n) {
        n = _readIni(L"defaults", iniSettingName, buffer, MAXLEN);
    }

    if (n) {
        wchar_t *tag = allocSearchInfoBuffer(search, n + 1);
        if (!tag) {
            return RC_NO_MEMORY;
        }
        wcscpy_s(tag, n + 1, buffer);
        wchar_t *slash = wcschr(tag, L'/');
        if (!slash) {
            search->tag = tag;
            search->tagLength = n;
            search->oldStyleTag = true;
        } else {
            search->company = tag;
            search->companyLength = (int)(slash - tag);
            search->tag = slash + 1;
            search->tagLength = n - (search->companyLength + 1);
            search->oldStyleTag = false;
        }
        // gh-92817: allow a high priority env to be selected even if it
        // doesn't match the tag
        search->lowPriorityTag = true;
    }

    return 0;
}

/******************************************************************************\
 ***                          ENVIRONMENT SEARCH                            ***
\******************************************************************************/

typedef struct EnvironmentInfo {
    /* We use a binary tree and sort on insert */
    struct EnvironmentInfo *prev;
    struct EnvironmentInfo *next;
    /* parent is only used when constructing */
    struct EnvironmentInfo *parent;
    const wchar_t *company;
    const wchar_t *tag;
    int internalSortKey;
    const wchar_t *installDir;
    const wchar_t *executablePath;
    const wchar_t *executableArgs;
    const wchar_t *architecture;
    const wchar_t *displayName;
    bool highPriority;
} EnvironmentInfo;


int
copyWstr(const wchar_t **dest, const wchar_t *src)
{
    if (!dest) {
        return RC_NO_MEMORY;
    }
    if (!src) {
        *dest = NULL;
        return 0;
    }
    size_t n = wcsnlen_s(src, MAXLEN - 1) + 1;
    wchar_t *buffer = (wchar_t*)malloc(n * sizeof(wchar_t));
    if (!buffer) {
        return RC_NO_MEMORY;
    }
    wcsncpy_s(buffer, n, src, n - 1);
    *dest = (const wchar_t*)buffer;
    return 0;
}


EnvironmentInfo *
newEnvironmentInfo(const wchar_t *company, const wchar_t *tag)
{
    EnvironmentInfo *env = (EnvironmentInfo *)malloc(sizeof(EnvironmentInfo));
    if (!env) {
        return NULL;
    }
    memset(env, 0, sizeof(EnvironmentInfo));
    int exitCode = copyWstr(&env->company, company);
    if (exitCode) {
        free((void *)env);
        return NULL;
    }
    exitCode = copyWstr(&env->tag, tag);
    if (exitCode) {
        free((void *)env->company);
        free((void *)env);
        return NULL;
    }
    return env;
}


void
freeEnvironmentInfo(EnvironmentInfo *env)
{
    if (env) {
        free((void *)env->company);
        free((void *)env->tag);
        free((void *)env->installDir);
        free((void *)env->executablePath);
        free((void *)env->executableArgs);
        free((void *)env->displayName);
        freeEnvironmentInfo(env->prev);
        env->prev = NULL;
        freeEnvironmentInfo(env->next);
        env->next = NULL;
        free((void *)env);
    }
}


/* Specific string comparisons for sorting the tree */

int
_compareCompany(const wchar_t *x, const wchar_t *y)
{
    if (!x && !y) {
        return 0;
    } else if (!x) {
        return -1;
    } else if (!y) {
        return 1;
    }

    bool coreX = 0 == _compare(x, -1, L"PythonCore", -1);
    bool coreY = 0 == _compare(y, -1, L"PythonCore", -1);
    if (coreX) {
        return coreY ? 0 : -1;
    } else if (coreY) {
        return 1;
    }
    return _compare(x, -1, y, -1);
}


int
_compareTag(const wchar_t *x, const wchar_t *y)
{
    if (!x && !y) {
        return 0;
    } else if (!x) {
        return -1;
    } else if (!y) {
        return 1;
    }

    // Compare up to the first dash. If not equal, that's our sort order
    const wchar_t *xDash = wcschr(x, L'-');
    const wchar_t *yDash = wcschr(y, L'-');
    int xToDash = xDash ? (int)(xDash - x) : -1;
    int yToDash = yDash ? (int)(yDash - y) : -1;
    int r = _compare(x, xToDash, y, yToDash);
    if (r) {
        return r;
    }
    // If we're equal up to the first dash, we want to sort one with
    // no dash *after* one with a dash. Otherwise, a reversed compare.
    // This works out because environments are sorted in descending tag
    // order, so that higher versions (probably) come first.
    // For PythonCore, our "X.Y" structure ensures that higher versions
    // come first. Everyone else will just have to deal with it.
    if (xDash && yDash) {
        return _compare(yDash, -1, xDash, -1);
    } else if (xDash) {
        return -1;
    } else if (yDash) {
        return 1;
    }
    return 0;
}


int
addEnvironmentInfo(EnvironmentInfo **root, EnvironmentInfo* parent, EnvironmentInfo *node)
{
    EnvironmentInfo *r = *root;
    if (!r) {
        *root = node;
        node->parent = parent;
        return 0;
    }
    // Sort by company name
    switch (_compareCompany(node->company, r->company)) {
    case -1:
        return addEnvironmentInfo(&r->prev, r, node);
    case 1:
        return addEnvironmentInfo(&r->next, r, node);
    case 0:
        break;
    }
    // Then by tag (descending)
    switch (_compareTag(node->tag, r->tag)) {
    case -1:
        return addEnvironmentInfo(&r->next, r, node);
    case 1:
        return addEnvironmentInfo(&r->prev, r, node);
    case 0:
        break;
    }
    // Then keep the one with the lowest internal sort key
    if (node->internalSortKey < r->internalSortKey) {
        // Replace the current node
        node->parent = r->parent;
        if (node->parent) {
            if (node->parent->prev == r) {
                node->parent->prev = node;
            } else if (node->parent->next == r) {
                node->parent->next = node;
            } else {
                debug(L"# Inconsistent parent value in tree\n");
                freeEnvironmentInfo(node);
                return RC_INTERNAL_ERROR;
            }
        } else {
            // If node has no parent, then it is the root.
            *root = node;
        }

        node->next = r->next;
        node->prev = r->prev;

        debug(L"# replaced %s/%s/%i in tree\n", node->company, node->tag, node->internalSortKey);
        freeEnvironmentInfo(r);
    } else {
        debug(L"# not adding %s/%s/%i to tree\n", node->company, node->tag, node->internalSortKey);
        return RC_DUPLICATE_ITEM;
    }
    return 0;
}


/******************************************************************************\
 ***                            REGISTRY SEARCH                             ***
\******************************************************************************/


int
_registryReadString(const wchar_t **dest, HKEY root, const wchar_t *subkey, const wchar_t *value)
{
    // Note that this is bytes (hence 'cb'), not characters ('cch')
    DWORD cbData = 0;
    DWORD flags = RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ;

    if (ERROR_SUCCESS != RegGetValueW(root, subkey, value, flags, NULL, NULL, &cbData)) {
        return 0;
    }

    wchar_t *buffer = (wchar_t*)malloc(cbData);
    if (!buffer) {
        return RC_NO_MEMORY;
    }

    if (ERROR_SUCCESS == RegGetValueW(root, subkey, value, flags, NULL, buffer, &cbData)) {
        *dest = buffer;
    } else {
        free((void *)buffer);
    }
    return 0;
}


int
_combineWithInstallDir(const wchar_t **dest, const wchar_t *installDir, const wchar_t *fragment, int fragmentLength)
{
    wchar_t buffer[MAXLEN];
    wchar_t fragmentBuffer[MAXLEN];
    if (wcsncpy_s(fragmentBuffer, MAXLEN, fragment, fragmentLength)) {
        return RC_NO_MEMORY;
    }

    if (FAILED(PathCchCombineEx(buffer, MAXLEN, installDir, fragmentBuffer, PATHCCH_ALLOW_LONG_PATHS))) {
        return RC_NO_MEMORY;
    }

    return copyWstr(dest, buffer);
}


bool
_isLegacyVersion(EnvironmentInfo *env)
{
    // Check if backwards-compatibility is required.
    // Specifically PythonCore versions 2.X and 3.0 - 3.5 do not implement PEP 514.
    if (0 != _compare(env->company, -1, L"PythonCore", -1)) {
        return false;
    }

    int versionMajor, versionMinor;
    int n = swscanf_s(env->tag, L"%d.%d", &versionMajor, &versionMinor);
    if (n != 2) {
        debug(L"# %s/%s has an invalid version tag\n", env->company, env->tag);
        return false;
    }

    return versionMajor == 2
        || (versionMajor == 3 && versionMinor >= 0 && versionMinor <= 5);
}

int
_registryReadLegacyEnvironment(const SearchInfo *search, HKEY root, EnvironmentInfo *env, const wchar_t *fallbackArch)
{
    // Backwards-compatibility for PythonCore versions which do not implement PEP 514.
    int exitCode = _combineWithInstallDir(
        &env->executablePath,
        env->installDir,
        search->executable,
        search->executableLength
    );
    if (exitCode) {
        return exitCode;
    }

    if (search->windowed) {
        exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"WindowedExecutableArguments");
    }
    else {
        exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"ExecutableArguments");
    }
    if (exitCode) {
        return exitCode;
    }

    if (fallbackArch) {
        copyWstr(&env->architecture, fallbackArch);
    } else {
        DWORD binaryType;
        BOOL success = GetBinaryTypeW(env->executablePath, &binaryType);
        if (!success) {
            return RC_NO_PYTHON;
        }

        switch (binaryType) {
        case SCS_32BIT_BINARY:
            copyWstr(&env->architecture, L"32bit");
            break;
        case SCS_64BIT_BINARY:
            copyWstr(&env->architecture, L"64bit");
            break;
        default:
            return RC_NO_PYTHON;
        }
    }

    if (0 == _compare(env->architecture, -1, L"32bit", -1)) {
        size_t tagLength = wcslen(env->tag);
        if (tagLength <= 3 || 0 != _compare(&env->tag[tagLength - 3], 3, L"-32", 3)) {
            const wchar_t *rawTag = env->tag;
            wchar_t *realTag = (wchar_t*) malloc(sizeof(wchar_t) * (tagLength + 4));
            if (!realTag) {
                return RC_NO_MEMORY;
            }

            int count = swprintf_s(realTag, tagLength + 4, L"%s-32", env->tag);
            if (count == -1) {
                debug(L"# Failed to generate 32bit tag\n");
                free(realTag);
                return RC_INTERNAL_ERROR;
            }

            env->tag = realTag;
            free((void*)rawTag);
        }
    }

    wchar_t buffer[MAXLEN];
    if (swprintf_s(buffer, MAXLEN, L"Python %s", env->tag)) {
        copyWstr(&env->displayName, buffer);
    }

    return 0;
}


int
_registryReadEnvironment(const SearchInfo *search, HKEY root, EnvironmentInfo *env, const wchar_t *fallbackArch)
{
    int exitCode = _registryReadString(&env->installDir, root, L"InstallPath", NULL);
    if (exitCode) {
        return exitCode;
    }
    if (!env->installDir) {
        return RC_NO_PYTHON;
    }

    if (_isLegacyVersion(env)) {
        return _registryReadLegacyEnvironment(search, root, env, fallbackArch);
    }

    // If pythonw.exe requested, check specific value
    if (search->windowed) {
        exitCode = _registryReadString(&env->executablePath, root, L"InstallPath", L"WindowedExecutablePath");
        if (!exitCode && env->executablePath) {
            exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"WindowedExecutableArguments");
        }
    }
    if (exitCode) {
        return exitCode;
    }

    // Missing windowed path or non-windowed request means we use ExecutablePath
    if (!env->executablePath) {
        exitCode = _registryReadString(&env->executablePath, root, L"InstallPath", L"ExecutablePath");
        if (!exitCode && env->executablePath) {
            exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"ExecutableArguments");
        }
    }
    if (exitCode) {
        return exitCode;
    }

    if (!env->executablePath) {
        debug(L"# %s/%s has no executable path\n", env->company, env->tag);
        return RC_NO_PYTHON;
    }

    exitCode = _registryReadString(&env->architecture, root, NULL, L"SysArchitecture");
    if (exitCode) {
        return exitCode;
    }

    exitCode = _registryReadString(&env->displayName, root, NULL, L"DisplayName");
    if (exitCode) {
        return exitCode;
    }

    return 0;
}

int
_registrySearchTags(const SearchInfo *search, EnvironmentInfo **result, HKEY root, int sortKey, const wchar_t *company, const wchar_t *fallbackArch)
{
    wchar_t buffer[256];
    int err = 0;
    int exitCode = 0;
    for (int i = 0; exitCode == 0; ++i) {
        DWORD cchBuffer = sizeof(buffer) / sizeof(buffer[0]);
        err = RegEnumKeyExW(root, i, buffer, &cchBuffer, NULL, NULL, NULL, NULL);
        if (err) {
            if (err != ERROR_NO_MORE_ITEMS) {
                winerror(0, L"Failed to read installs (tags) from the registry");
            }
            break;
        }
        HKEY subkey;
        if (ERROR_SUCCESS == RegOpenKeyExW(root, buffer, 0, KEY_READ, &subkey)) {
            EnvironmentInfo *env = newEnvironmentInfo(company, buffer);
            env->internalSortKey = sortKey;
            exitCode = _registryReadEnvironment(search, subkey, env, fallbackArch);
            RegCloseKey(subkey);
            if (exitCode == RC_NO_PYTHON) {
                freeEnvironmentInfo(env);
                exitCode = 0;
            } else if (!exitCode) {
                exitCode = addEnvironmentInfo(result, NULL, env);
                if (exitCode) {
                    freeEnvironmentInfo(env);
                    if (exitCode == RC_DUPLICATE_ITEM) {
                        exitCode = 0;
                    }
                }
            }
        }
    }
    return exitCode;
}


int
registrySearch(const SearchInfo *search, EnvironmentInfo **result, HKEY root, int sortKey, const wchar_t *fallbackArch)
{
    wchar_t buffer[256];
    int err = 0;
    int exitCode = 0;
    for (int i = 0; exitCode == 0; ++i) {
        DWORD cchBuffer = sizeof(buffer) / sizeof(buffer[0]);
        err = RegEnumKeyExW(root, i, buffer, &cchBuffer, NULL, NULL, NULL, NULL);
        if (err) {
            if (err != ERROR_NO_MORE_ITEMS) {
                winerror(0, L"Failed to read distributors (company) from the registry");
            }
            break;
        }
        if (search->limitToCompany && 0 != _compare(search->limitToCompany, -1, buffer, cchBuffer)) {
            debug(L"# Skipping %s due to PYLAUNCHER_LIMIT_TO_COMPANY\n", buffer);
            continue;
        }
        HKEY subkey;
        if (ERROR_SUCCESS == RegOpenKeyExW(root, buffer, 0, KEY_READ, &subkey)) {
            exitCode = _registrySearchTags(search, result, subkey, sortKey, buffer, fallbackArch);
            RegCloseKey(subkey);
        }
    }
    return exitCode;
}


/******************************************************************************\
 ***                            APP PACKAGE SEARCH                          ***
\******************************************************************************/

int
appxSearch(const SearchInfo *search, EnvironmentInfo **result, const wchar_t *packageFamilyName, const wchar_t *tag, int sortKey)
{
    wchar_t realTag[32];
    wchar_t buffer[MAXLEN];
    const wchar_t *exeName = search->executable;
    if (!exeName || search->allowExecutableOverride) {
        exeName = search->windowed ? L"pythonw.exe" : L"python.exe";
    }

    // Failure to get LocalAppData may just mean we're running as a user who
    // doesn't have a profile directory.
    // In this case, return "not found", but don't fail.
    // Chances are they can't launch Store installs anyway.
    if (FAILED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, buffer))) {
        return RC_NO_PYTHON;
    }

    if (!join(buffer, MAXLEN, L"Microsoft\\WindowsApps") ||
        !join(buffer, MAXLEN, packageFamilyName) ||
        !join(buffer, MAXLEN, exeName)) {
        debug(L"# Failed to construct App Execution Alias path\n");
        return RC_INTERNAL_ERROR;
    }

    if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(buffer)) {
        return RC_NO_PYTHON;
    }

    // Assume packages are native architecture, which means we need to append
    // the '-arm64' on ARM64 host.
    wcscpy_s(realTag, 32, tag);
    if (isARM64Host()) {
        wcscat_s(realTag, 32, L"-arm64");
    }

    EnvironmentInfo *env = newEnvironmentInfo(L"PythonCore", realTag);
    if (!env) {
        return RC_NO_MEMORY;
    }
    env->internalSortKey = sortKey;
    if (isAMD64Host()) {
        copyWstr(&env->architecture, L"64bit");
    } else if (isARM64Host()) {
        copyWstr(&env->architecture, L"ARM64");
    }

    copyWstr(&env->executablePath, buffer);

    if (swprintf_s(buffer, MAXLEN, L"Python %s (Store)", tag)) {
        copyWstr(&env->displayName, buffer);
    }

    int exitCode = addEnvironmentInfo(result, NULL, env);
    if (exitCode) {
        freeEnvironmentInfo(env);
        if (exitCode == RC_DUPLICATE_ITEM) {
            exitCode = 0;
        }
    }


    return exitCode;
}


/******************************************************************************\
 ***                      OVERRIDDEN EXECUTABLE PATH                        ***
\******************************************************************************/


int
explicitOverrideSearch(const SearchInfo *search, EnvironmentInfo **result)
{
    if (!search->executablePath) {
        return 0;
    }

    EnvironmentInfo *env = newEnvironmentInfo(NULL, NULL);
    if (!env) {
        return RC_NO_MEMORY;
    }
    env->internalSortKey = 10;
    int exitCode = copyWstr(&env->executablePath, search->executablePath);
    if (exitCode) {
        goto abort;
    }
    exitCode = copyWstr(&env->displayName, L"Explicit override");
    if (exitCode) {
        goto abort;
    }
    exitCode = addEnvironmentInfo(result, NULL, env);
    if (exitCode) {
        goto abort;
    }
    return 0;

abort:
    freeEnvironmentInfo(env);
    if (exitCode == RC_DUPLICATE_ITEM) {
        exitCode = 0;
    }
    return exitCode;
}


/******************************************************************************\
 ***                   ACTIVE VIRTUAL ENVIRONMENT SEARCH                    ***
\******************************************************************************/

int
virtualenvSearch(const SearchInfo *search, EnvironmentInfo **result)
{
    int exitCode = 0;
    EnvironmentInfo *env = NULL;
    wchar_t buffer[MAXLEN];
    int n = GetEnvironmentVariableW(L"VIRTUAL_ENV", buffer, MAXLEN);
    if (!n || !join(buffer, MAXLEN, L"Scripts") || !join(buffer, MAXLEN, search->executable)) {
        return 0;
    }

    DWORD attr = GetFileAttributesW(buffer);
    if (INVALID_FILE_ATTRIBUTES == attr && search->lowPriorityTag) {
        if (!split_parent(buffer, MAXLEN) || !join(buffer, MAXLEN, L"python.exe")) {
            return 0;
        }
        attr = GetFileAttributesW(buffer);
    }

    if (INVALID_FILE_ATTRIBUTES == attr) {
        debug(L"Python executable %s missing from virtual env\n", buffer);
        return 0;
    }

    env = newEnvironmentInfo(NULL, NULL);
    if (!env) {
        return RC_NO_MEMORY;
    }
    env->highPriority = true;
    env->internalSortKey = 20;
    exitCode = copyWstr(&env->displayName, L"Active venv");
    if (exitCode) {
        goto abort;
    }
    exitCode = copyWstr(&env->executablePath, buffer);
    if (exitCode) {
        goto abort;
    }
    exitCode = addEnvironmentInfo(result, NULL, env);
    if (exitCode) {
        goto abort;
    }
    return 0;

abort:
    freeEnvironmentInfo(env);
    if (exitCode == RC_DUPLICATE_ITEM) {
        return 0;
    }
    return exitCode;
}

/******************************************************************************\
 ***                           COLLECT ENVIRONMENTS                         ***
\******************************************************************************/


struct RegistrySearchInfo {
    // Registry subkey to search
    const wchar_t *subkey;
    // Registry hive to search
    HKEY hive;
    // Flags to use when opening the subkey
    DWORD flags;
    // Internal sort key to select between "identical" environments discovered
    // through different methods
    int sortKey;
    // Fallback value to assume for PythonCore entries missing a SysArchitecture value
    const wchar_t *fallbackArch;
};


struct RegistrySearchInfo REGISTRY_SEARCH[] = {
    {
        L"Software\\Python",
        HKEY_CURRENT_USER,
        KEY_READ,
        1,
        NULL
    },
    {
        L"Software\\Python",
        HKEY_LOCAL_MACHINE,
        KEY_READ | KEY_WOW64_64KEY,
        3,
        L"64bit"
    },
    {
        L"Software\\Python",
        HKEY_LOCAL_MACHINE,
        KEY_READ | KEY_WOW64_32KEY,
        4,
        L"32bit"
    },
    { NULL, 0, 0, 0, NULL }
};


struct AppxSearchInfo {
    // The package family name. Can be found for an installed package using the
    // Powershell "Get-AppxPackage" cmdlet
    const wchar_t *familyName;
    // The tag to treat the installation as
    const wchar_t *tag;
    // Internal sort key to select between "identical" environments discovered
    // through different methods
    int sortKey;
};


struct AppxSearchInfo APPX_SEARCH[] = {
    // Releases made through the Store
    { L"PythonSoftwareFoundation.Python.3.14_qbz5n2kfra8p0", L"3.14", 10 },
    { L"PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0", L"3.13", 10 },
    { L"PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0", L"3.12", 10 },
    { L"PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0", L"3.11", 10 },
    { L"PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0", L"3.10", 10 },
    { L"PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0", L"3.9", 10 },
    { L"PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0", L"3.8", 10 },

    // Side-loadable releases. Note that the publisher ID changes whenever we
    // change our code signing certificate subject, so the newer IDs have higher
    // priorities (lower sortKey)
    { L"PythonSoftwareFoundation.Python.3.14_3847v3x7pw1km", L"3.14", 11 },
    { L"PythonSoftwareFoundation.Python.3.13_3847v3x7pw1km", L"3.13", 11 },
    { L"PythonSoftwareFoundation.Python.3.12_3847v3x7pw1km", L"3.12", 11 },
    { L"PythonSoftwareFoundation.Python.3.11_3847v3x7pw1km", L"3.11", 11 },
    { L"PythonSoftwareFoundation.Python.3.11_hd69rhyc2wevp", L"3.11", 12 },
    { L"PythonSoftwareFoundation.Python.3.10_3847v3x7pw1km", L"3.10", 11 },
    { L"PythonSoftwareFoundation.Python.3.10_hd69rhyc2wevp", L"3.10", 12 },
    { L"PythonSoftwareFoundation.Python.3.9_3847v3x7pw1km", L"3.9", 11 },
    { L"PythonSoftwareFoundation.Python.3.9_hd69rhyc2wevp", L"3.9", 12 },
    { L"PythonSoftwareFoundation.Python.3.8_hd69rhyc2wevp", L"3.8", 12 },
    { NULL, NULL, 0 }
};


int
collectEnvironments(const SearchInfo *search, EnvironmentInfo **result)
{
    int exitCode = 0;
    HKEY root;
    EnvironmentInfo *env = NULL;

    if (!result) {
        debug(L"# collectEnvironments() was passed a NULL result\n");
        return RC_INTERNAL_ERROR;
    }
    *result = NULL;

    exitCode = explicitOverrideSearch(search, result);
    if (exitCode) {
        return exitCode;
    }

    exitCode = virtualenvSearch(search, result);
    if (exitCode) {
        return exitCode;
    }

    // If we aren't collecting all items to list them, we can exit now.
    if (env && !(search->list || search->listPaths)) {
        return 0;
    }

    for (struct RegistrySearchInfo *info = REGISTRY_SEARCH; info->subkey; ++info) {
        if (ERROR_SUCCESS == RegOpenKeyExW(info->hive, info->subkey, 0, info->flags, &root)) {
            exitCode = registrySearch(search, result, root, info->sortKey, info->fallbackArch);
            RegCloseKey(root);
        }
        if (exitCode) {
            return exitCode;
        }
    }

    if (search->limitToCompany) {
        debug(L"# Skipping APPX search due to PYLAUNCHER_LIMIT_TO_COMPANY\n");
        return 0;
    }

    for (struct AppxSearchInfo *info = APPX_SEARCH; info->familyName; ++info) {
        exitCode = appxSearch(search, result, info->familyName, info->tag, info->sortKey);
        if (exitCode && exitCode != RC_NO_PYTHON) {
            return exitCode;
        }
    }

    return 0;
}


/******************************************************************************\
 ***                           INSTALL ON DEMAND                            ***
\******************************************************************************/

struct StoreSearchInfo {
    // The tag a user is looking for
    const wchar_t *tag;
    // The Store ID for a package if it can be installed from the Microsoft
    // Store. These are obtained from the dashboard at
    // https://partner.microsoft.com/dashboard
    const wchar_t *storeId;
};


struct StoreSearchInfo STORE_SEARCH[] = {
    { L"3", /* 3.13 */ L"9PNRBTZXMB4Z" },
    { L"3.14", L"9NTRHQCBBPR8" },
    { L"3.13", L"9PNRBTZXMB4Z" },
    { L"3.12", L"9NCVDN91XZQP" },
    { L"3.11", L"9NRWMJP3717K" },
    { L"3.10", L"9PJPW5LDXLZ5" },
    { L"3.9", L"9P7QFQMJRFP7" },
    { L"3.8", L"9MSSZTT1N39L" },
    { NULL, NULL }
};


int
_installEnvironment(const wchar_t *command, const wchar_t *arguments)
{
    SHELLEXECUTEINFOW siw = {
        sizeof(SHELLEXECUTEINFOW),
        SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE,
        NULL, NULL,
        command, arguments, NULL,
        SW_SHOWNORMAL
    };

    debug(L"# Installing with %s %s\n", command, arguments);
    if (isEnvVarSet(L"PYLAUNCHER_DRYRUN")) {
        debug(L"# Exiting due to PYLAUNCHER_DRYRUN\n");
        fflush(stdout);
        int mode = _setmode(_fileno(stdout), _O_U8TEXT);
        if (arguments) {
            fwprintf_s(stdout, L"\"%s\" %s\n", command, arguments);
        } else {
            fwprintf_s(stdout, L"\"%s\"\n", command);
        }
        fflush(stdout);
        if (mode >= 0) {
            _setmode(_fileno(stdout), mode);
        }
        return RC_INSTALLING;
    }

    if (!ShellExecuteExW(&siw)) {
        return RC_NO_PYTHON;
    }

    if (!siw.hProcess) {
        return RC_INSTALLING;
    }

    WaitForSingleObjectEx(siw.hProcess, INFINITE, FALSE);
    DWORD exitCode = 0;
    if (GetExitCodeProcess(siw.hProcess, &exitCode) && exitCode == 0) {
        return 0;
    }
    return RC_INSTALLING;
}


const wchar_t *WINGET_COMMAND = L"Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\winget.exe";
const wchar_t *WINGET_ARGUMENTS = L"install -q %s --exact --accept-package-agreements --source msstore";

const wchar_t *MSSTORE_COMMAND = L"ms-windows-store://pdp/?productid=%s";

int
installEnvironment(const SearchInfo *search)
{
    // No tag? No installing
    if (!search->tag || !search->tagLength) {
        debug(L"# Cannot install Python with no tag specified\n");
        return RC_NO_PYTHON;
    }

    // PEP 514 tag but not PythonCore? No installing
    if (!search->oldStyleTag &&
        search->company && search->companyLength &&
        0 != _compare(search->company, search->companyLength, L"PythonCore", -1)) {
        debug(L"# Cannot install for company %.*s\n", search->companyLength, search->company);
        return RC_NO_PYTHON;
    }

    const wchar_t *storeId = NULL;
    for (struct StoreSearchInfo *info = STORE_SEARCH; info->tag; ++info) {
        if (0 == _compare(search->tag, search->tagLength, info->tag, -1)) {
            storeId = info->storeId;
            break;
        }
    }

    if (!storeId) {
        return RC_NO_PYTHON;
    }

    int exitCode;
    wchar_t command[MAXLEN];
    wchar_t arguments[MAXLEN];
    if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, command)) &&
        join(command, MAXLEN, WINGET_COMMAND) &&
        swprintf_s(arguments, MAXLEN, WINGET_ARGUMENTS, storeId)) {
        if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(command)) {
            formatWinerror(GetLastError(), arguments, MAXLEN);
            debug(L"# Skipping %s: %s\n", command, arguments);
        } else {
            fputws(L"Launching winget to install Python. The following output is from the install process\n\
***********************************************************************\n", stdout);
            exitCode = _installEnvironment(command, arguments);
            if (exitCode == RC_INSTALLING) {
                fputws(L"***********************************************************************\n\
Please check the install status and run your command again.", stderr);
                return exitCode;
            } else if (exitCode) {
                return exitCode;
            }
            fputws(L"***********************************************************************\n\
Install appears to have succeeded. Searching for new matching installs.\n", stdout);
            return 0;
        }
    }

    if (swprintf_s(command, MAXLEN, MSSTORE_COMMAND, storeId)) {
        fputws(L"Opening the Microsoft Store to install Python. After installation, "
               L"please run your command again.\n", stderr);
        exitCode = _installEnvironment(command, NULL);
        if (exitCode) {
            return exitCode;
        }
        return 0;
    }

    return RC_NO_PYTHON;
}

/******************************************************************************\
 ***                           ENVIRONMENT SELECT                           ***
\******************************************************************************/

bool
_companyMatches(const SearchInfo *search, const EnvironmentInfo *env)
{
    if (!search->company || !search->companyLength) {
        return true;
    }
    return 0 == _compare(env->company, -1, search->company, search->companyLength);
}


bool
_tagMatches(const SearchInfo *search, const EnvironmentInfo *env, int searchTagLength)
{
    if (searchTagLength < 0) {
        searchTagLength = search->tagLength;
    }
    if (!search->tag || !searchTagLength) {
        return true;
    }
    return _startsWithSeparated(env->tag, -1, search->tag, searchTagLength, L".-");
}


bool
_is32Bit(const EnvironmentInfo *env)
{
    if (env->architecture) {
        return 0 == _compare(env->architecture, -1, L"32bit", -1);
    }
    return false;
}


int
_selectEnvironment(const SearchInfo *search, EnvironmentInfo *env, EnvironmentInfo **best)
{
    int exitCode = 0;
    while (env) {
        exitCode = _selectEnvironment(search, env->prev, best);

        if (exitCode && exitCode != RC_NO_PYTHON) {
            return exitCode;
        } else if (!exitCode && *best) {
            return 0;
        }

        if (env->highPriority && search->lowPriorityTag) {
            // This environment is marked high priority, and the search allows
            // it to be selected even though a tag is specified, so select it
            // gh-92817: this allows an active venv to be selected even when a
            // default tag has been found in py.ini or the environment
            *best = env;
            return 0;
        }

        if (!search->oldStyleTag) {
            if (_companyMatches(search, env) && _tagMatches(search, env, -1)) {
                // Because of how our sort tree is set up, we will walk up the
                // "prev" side and implicitly select the "best" best. By
                // returning straight after a match, we skip the entire "next"
                // branch and won't ever select a "worse" best.
                *best = env;
                return 0;
            }
        } else if (0 == _compare(env->company, -1, L"PythonCore", -1)) {
            // Old-style tags can only match PythonCore entries

            // If the tag ends with -64, we want to exclude 32-bit runtimes
            // (If the tag ends with -32, it will be filtered later)
            int tagLength = search->tagLength;
            bool exclude32Bit = false, only32Bit = false;
            if (tagLength > 3) {
                if (0 == _compareArgument(&search->tag[tagLength - 3], 3, L"-64", 3)) {
                    tagLength -= 3;
                    exclude32Bit = true;
                } else if (0 == _compareArgument(&search->tag[tagLength - 3], 3, L"-32", 3)) {
                    tagLength -= 3;
                    only32Bit = true;
                }
            }

            if (_tagMatches(search, env, tagLength)) {
                if (exclude32Bit && _is32Bit(env)) {
                    debug(L"# Excluding %s/%s because it looks like 32bit\n", env->company, env->tag);
                } else if (only32Bit && !_is32Bit(env)) {
                    debug(L"# Excluding %s/%s because it doesn't look 32bit\n", env->company, env->tag);
                } else {
                    *best = env;
                    return 0;
                }
            }
        }

        env = env->next;
    }
    return RC_NO_PYTHON;
}

int
selectEnvironment(const SearchInfo *search, EnvironmentInfo *root, EnvironmentInfo **best)
{
    if (!best) {
        debug(L"# selectEnvironment() was passed a NULL best\n");
        return RC_INTERNAL_ERROR;
    }
    if (!root) {
        *best = NULL;
        return RC_NO_PYTHON_AT_ALL;
    }

    EnvironmentInfo *result = NULL;
    int exitCode = _selectEnvironment(search, root, &result);
    if (!exitCode) {
        *best = result;
    }

    return exitCode;
}


/******************************************************************************\
 ***                            LIST ENVIRONMENTS                           ***
\******************************************************************************/

#define TAGWIDTH 16

int
_printEnvironment(const EnvironmentInfo *env, FILE *out, bool showPath, const wchar_t *argument)
{
    if (showPath) {
        if (env->executablePath && env->executablePath[0]) {
            if (env->executableArgs && env->executableArgs[0]) {
                fwprintf(out, L" %-*s %s %s\n", TAGWIDTH, argument, env->executablePath, env->executableArgs);
            } else {
                fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->executablePath);
            }
        } else if (env->installDir && env->installDir[0]) {
            fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->installDir);
        } else {
            fwprintf(out, L" %s\n", argument);
        }
    } else if (env->displayName) {
        fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->displayName);
    } else {
        fwprintf(out, L" %s\n", argument);
    }
    return 0;
}


int
_listAllEnvironments(EnvironmentInfo *env, FILE * out, bool showPath, EnvironmentInfo *defaultEnv)
{
    wchar_t buffer[256];
    const int bufferSize = 256;
    while (env) {
        int exitCode = _listAllEnvironments(env->prev, out, showPath, defaultEnv);
        if (exitCode) {
            return exitCode;
        }

        if (!env->company || !env->tag) {
            buffer[0] = L'\0';
        } else if (0 == _compare(env->company, -1, L"PythonCore", -1)) {
            swprintf_s(buffer, bufferSize, L"-V:%s", env->tag);
        } else {
            swprintf_s(buffer, bufferSize, L"-V:%s/%s", env->company, env->tag);
        }

        if (env == defaultEnv) {
            wcscat_s(buffer, bufferSize, L" *");
        }

        if (buffer[0]) {
            exitCode = _printEnvironment(env, out, showPath, buffer);
            if (exitCode) {
                return exitCode;
            }
        }

        env = env->next;
    }
    return 0;
}


int
listEnvironments(EnvironmentInfo *env, FILE * out, bool showPath, EnvironmentInfo *defaultEnv)
{
    if (!env) {
        fwprintf_s(stdout, L"No installed Pythons found!\n");
        return 0;
    }

    /* TODO: Do we want to display these?
       In favour, helps users see that '-3' is a good option
       Against, repeats the next line of output
    SearchInfo majorSearch;
    EnvironmentInfo *major;
    int exitCode;

    if (showPath) {
        memset(&majorSearch, 0, sizeof(majorSearch));
        majorSearch.company = L"PythonCore";
        majorSearch.companyLength = -1;
        majorSearch.tag = L"3";
        majorSearch.tagLength = -1;
        majorSearch.oldStyleTag = true;
        major = NULL;
        exitCode = selectEnvironment(&majorSearch, env, &major);
        if (!exitCode && major) {
            exitCode = _printEnvironment(major, out, showPath, L"-3 *");
            isDefault = false;
            if (exitCode) {
                return exitCode;
            }
        }
        majorSearch.tag = L"2";
        major = NULL;
        exitCode = selectEnvironment(&majorSearch, env, &major);
        if (!exitCode && major) {
            exitCode = _printEnvironment(major, out, showPath, L"-2");
            if (exitCode) {
                return exitCode;
            }
        }
    }
    */

    int mode = _setmode(_fileno(out), _O_U8TEXT);
    int exitCode = _listAllEnvironments(env, out, showPath, defaultEnv);
    fflush(out);
    if (mode >= 0) {
        _setmode(_fileno(out), mode);
    }
    return exitCode;
}


/******************************************************************************\
 ***                           INTERPRETER LAUNCH                           ***
\******************************************************************************/


int
calculateCommandLine(const SearchInfo *search, const EnvironmentInfo *launch, wchar_t *buffer, int bufferLength)
{
    int exitCode = 0;
    const wchar_t *executablePath = NULL;

    // Construct command line from a search override, or else the selected
    // environment's executablePath
    if (search->executablePath) {
        executablePath = search->executablePath;
    } else if (launch && launch->executablePath) {
        executablePath = launch->executablePath;
    }

    // If we have an executable path, put it at the start of the command, but
    // only if the search allowed an override.
    // Otherwise, use the environment's installDir and the search's default
    // executable name.
    if (executablePath && search->allowExecutableOverride) {
        if (wcschr(executablePath, L' ') && executablePath[0] != L'"') {
            buffer[0] = L'"';
            exitCode = wcscpy_s(&buffer[1], bufferLength - 1, executablePath);
            if (!exitCode) {
                exitCode = wcscat_s(buffer, bufferLength, L"\"");
            }
        } else {
            exitCode = wcscpy_s(buffer, bufferLength, executablePath);
        }
    } else if (launch) {
        if (!launch->installDir) {
            fwprintf_s(stderr, L"Cannot launch %s %s because no install directory was specified",
                       launch->company, launch->tag);
            exitCode = RC_NO_PYTHON;
        } else if (!search->executable || !search->executableLength) {
            fwprintf_s(stderr, L"Cannot launch %s %s because no executable name is available",
                       launch->company, launch->tag);
            exitCode = RC_NO_PYTHON;
        } else {
            wchar_t executable[256];
            wcsncpy_s(executable, 256, search->executable, search->executableLength);
            if ((wcschr(launch->installDir, L' ') && launch->installDir[0] != L'"') ||
                (wcschr(executable, L' ') && executable[0] != L'"')) {
                buffer[0] = L'"';
                exitCode = wcscpy_s(&buffer[1], bufferLength - 1, launch->installDir);
                if (!exitCode) {
                    exitCode = join(buffer, bufferLength, executable) ? 0 : RC_NO_MEMORY;
                }
                if (!exitCode) {
                    exitCode = wcscat_s(buffer, bufferLength, L"\"");
                }
            } else {
                exitCode = wcscpy_s(buffer, bufferLength, launch->installDir);
                if (!exitCode) {
                    exitCode = join(buffer, bufferLength, executable) ? 0 : RC_NO_MEMORY;
                }
            }
        }
    } else {
        exitCode = RC_NO_PYTHON;
    }

    if (!exitCode && launch && launch->executableArgs) {
        exitCode = wcscat_s(buffer, bufferLength, L" ");
        if (!exitCode) {
            exitCode = wcscat_s(buffer, bufferLength, launch->executableArgs);
        }
    }

    if (!exitCode && search->executableArgs) {
        if (search->executableArgsLength < 0) {
            exitCode = wcscat_s(buffer, bufferLength, search->executableArgs);
        } else if (search->executableArgsLength > 0) {
            int end = (int)wcsnlen_s(buffer, MAXLEN);
            if (end < bufferLength - (search->executableArgsLength + 1)) {
                exitCode = wcsncpy_s(&buffer[end], bufferLength - end,
                    search->executableArgs, search->executableArgsLength);
            }
        }
    }

    if (!exitCode && search->restOfCmdLine) {
        exitCode = wcscat_s(buffer, bufferLength, search->restOfCmdLine);
    }

    return exitCode;
}



BOOL
_safeDuplicateHandle(HANDLE in, HANDLE * pout, const wchar_t *nameForError)
{
    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 {
            winerror(0, L"Failed to duplicate %s handle", nameForError);
        }
    }
    return ok;
}

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


int
launchEnvironment(const SearchInfo *search, const EnvironmentInfo *launch, wchar_t *launchCommand)
{
    HANDLE job;
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
    DWORD rc;
    BOOL ok;
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;

    // If this is a dryrun, do not actually launch
    if (isEnvVarSet(L"PYLAUNCHER_DRYRUN")) {
        debug(L"LaunchCommand: %s\n", launchCommand);
        debug(L"# Exiting due to PYLAUNCHER_DRYRUN variable\n");
        fflush(stdout);
        int mode = _setmode(_fileno(stdout), _O_U8TEXT);
        fwprintf(stdout, L"%s\n", launchCommand);
        fflush(stdout);
        if (mode >= 0) {
            _setmode(_fileno(stdout), mode);
        }
        return 0;
    }

#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
    */
    MSG msg;

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

    debug(L"# about to run: %s\n", launchCommand);
    job = CreateJobObject(NULL, NULL);
    ok = QueryInformationJobObject(job, JobObjectExtendedLimitInformation,
                                  &info, sizeof(info), &rc);
    if (!ok || (rc != sizeof(info)) || !job) {
        winerror(0, L"Failed to query job information");
        return RC_CREATE_PROCESS;
    }
    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) {
        winerror(0, L"Failed to update job information");
        return RC_CREATE_PROCESS;
    }
    memset(&si, 0, sizeof(si));
    GetStartupInfoW(&si);
    if (!_safeDuplicateHandle(GetStdHandle(STD_INPUT_HANDLE), &si.hStdInput, L"stdin") ||
        !_safeDuplicateHandle(GetStdHandle(STD_OUTPUT_HANDLE), &si.hStdOutput, L"stdout") ||
        !_safeDuplicateHandle(GetStdHandle(STD_ERROR_HANDLE), &si.hStdError, L"stderr")) {
        return RC_NO_STD_HANDLES;
    }

    ok = SetConsoleCtrlHandler(ctrl_c_handler, TRUE);
    if (!ok) {
        winerror(0, L"Failed to update Control-C handler");
        return RC_NO_STD_HANDLES;
    }

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


/******************************************************************************\
 ***                           PROCESS CONTROLLER                           ***
\******************************************************************************/


int
performSearch(SearchInfo *search, EnvironmentInfo **envs)
{
    // First parse the command line for options
    int exitCode = parseCommandLine(search);
    if (exitCode) {
        return exitCode;
    }

    // Check for a shebang line in our script file
    // (or return quickly if no script file was specified)
    exitCode = checkShebang(search);
    switch (exitCode) {
    case 0:
    case RC_NO_SHEBANG:
    case RC_RECURSIVE_SHEBANG:
        break;
    default:
        return exitCode;
    }

    // Resolve old-style tags (possibly from a shebang) against py.ini entries
    // and environment variables.
    exitCode = checkDefaults(search);
    if (exitCode) {
        return exitCode;
    }

    // If debugging is enabled, list our search criteria
    dumpSearchInfo(search);

    // Find all matching environments
    exitCode = collectEnvironments(search, envs);
    if (exitCode) {
        return exitCode;
    }

    return 0;
}


int
process(int argc, wchar_t ** argv)
{
    int exitCode = 0;
    int searchExitCode = 0;
    SearchInfo search = {0};
    EnvironmentInfo *envs = NULL;
    EnvironmentInfo *env = NULL;
    wchar_t launchCommand[MAXLEN];

    memset(launchCommand, 0, sizeof(launchCommand));

    if (isEnvVarSet(L"PYLAUNCHER_DEBUG")) {
        setvbuf(stderr, (char *)NULL, _IONBF, 0);
        log_fp = stderr;
        debug(L"argv0: %s\nversion: %S\n", argv[0], PY_VERSION);
    }

    DWORD len = GetEnvironmentVariableW(L"PYLAUNCHER_LIMIT_TO_COMPANY", NULL, 0);
    if (len > 1) {
        wchar_t *limitToCompany = allocSearchInfoBuffer(&search, len);
        if (!limitToCompany) {
            exitCode = RC_NO_MEMORY;
            winerror(0, L"Failed to allocate internal buffer");
            goto abort;
        }
        search.limitToCompany = limitToCompany;
        if (0 == GetEnvironmentVariableW(L"PYLAUNCHER_LIMIT_TO_COMPANY", limitToCompany, len)) {
            exitCode = RC_INTERNAL_ERROR;
            winerror(0, L"Failed to read PYLAUNCHER_LIMIT_TO_COMPANY variable");
            goto abort;
        }
    }

    search.originalCmdLine = GetCommandLineW();

    exitCode = performSearch(&search, &envs);
    if (exitCode) {
        goto abort;
    }

    // Display the help text, but only exit on error
    if (search.help) {
        exitCode = showHelpText(argv);
        if (exitCode) {
            goto abort;
        }
    }

    // Select best environment
    // This is early so that we can show the default when listing, but all
    // responses to any errors occur later.
    searchExitCode = selectEnvironment(&search, envs, &env);

    // List all environments, then exit
    if (search.list || search.listPaths) {
        exitCode = listEnvironments(envs, stdout, search.listPaths, env);
        goto abort;
    }

    // When debugging, list all discovered environments anyway
    if (log_fp) {
        exitCode = listEnvironments(envs, log_fp, true, NULL);
        if (exitCode) {
            goto abort;
        }
    }

    // We searched earlier, so if we didn't find anything, now we react
    exitCode = searchExitCode;
    // If none found, and if permitted, install it
    if (((exitCode == RC_NO_PYTHON) && isEnvVarSet(L"PYLAUNCHER_ALLOW_INSTALL")) ||
        isEnvVarSet(L"PYLAUNCHER_ALWAYS_INSTALL")) {
        exitCode = installEnvironment(&search);
        if (!exitCode) {
            // Successful install, so we need to re-scan and select again
            env = NULL;
            exitCode = performSearch(&search, &envs);
            if (exitCode) {
                goto abort;
            }
            exitCode = selectEnvironment(&search, envs, &env);
        }
    }
    if (exitCode == RC_NO_PYTHON) {
        fputws(L"No suitable Python runtime found\n", stderr);
        fputws(L"Pass --list (-0) to see all detected environments on your machine\n", stderr);
        if (!isEnvVarSet(L"PYLAUNCHER_ALLOW_INSTALL") && search.oldStyleTag) {
            fputws(L"or set environment variable PYLAUNCHER_ALLOW_INSTALL to use winget\n"
                   L"or open the Microsoft Store to the requested version.\n", stderr);
        }
        goto abort;
    }
    if (exitCode == RC_NO_PYTHON_AT_ALL) {
        fputws(L"No installed Python found!\n", stderr);
        goto abort;
    }
    if (exitCode) {
        goto abort;
    }

    if (env) {
        debug(L"env.company: %s\nenv.tag: %s\n", env->company, env->tag);
    } else {
        debug(L"env.company: (null)\nenv.tag: (null)\n");
    }

    exitCode = calculateCommandLine(&search, env, launchCommand, sizeof(launchCommand) / sizeof(launchCommand[0]));
    if (exitCode) {
        goto abort;
    }

    // Launch selected runtime
    exitCode = launchEnvironment(&search, env, launchCommand);

abort:
    freeSearchInfo(&search);
    freeEnvironmentInfo(envs);
    return exitCode;
}


#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
