/*
 * 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;
    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);


    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)) { }
    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, 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
