//-------------------------------------------------------------------------------------------------
// <copyright file="WixStandardBootstrapperApplication.cpp" company="Outercurve Foundation">
//   Copyright (c) 2004, Outercurve Foundation.
//   This software is released under Microsoft Reciprocal License (MS-RL).
//   The license and further copyright text can be found in the file
//   LICENSE.TXT at the root directory of the distribution.
// </copyright>
//-------------------------------------------------------------------------------------------------


#include "pch.h"

static const LPCWSTR PYBA_WINDOW_CLASS = L"PythonBA";
static const DWORD PYBA_ACQUIRE_PERCENTAGE = 30;
static const LPCWSTR PYBA_VARIABLE_BUNDLE_FILE_VERSION = L"WixBundleFileVersion";

enum PYBA_STATE {
    PYBA_STATE_INITIALIZING,
    PYBA_STATE_INITIALIZED,
    PYBA_STATE_HELP,
    PYBA_STATE_DETECTING,
    PYBA_STATE_DETECTED,
    PYBA_STATE_PLANNING,
    PYBA_STATE_PLANNED,
    PYBA_STATE_APPLYING,
    PYBA_STATE_CACHING,
    PYBA_STATE_CACHED,
    PYBA_STATE_EXECUTING,
    PYBA_STATE_EXECUTED,
    PYBA_STATE_APPLIED,
    PYBA_STATE_FAILED,
};

static const int WM_PYBA_SHOW_HELP = WM_APP + 100;
static const int WM_PYBA_DETECT_PACKAGES = WM_APP + 101;
static const int WM_PYBA_PLAN_PACKAGES = WM_APP + 102;
static const int WM_PYBA_APPLY_PACKAGES = WM_APP + 103;
static const int WM_PYBA_CHANGE_STATE = WM_APP + 104;
static const int WM_PYBA_SHOW_FAILURE = WM_APP + 105;

// This enum must be kept in the same order as the PAGE_NAMES array.
enum PAGE {
    PAGE_LOADING,
    PAGE_HELP,
    PAGE_INSTALL,
    PAGE_UPGRADE,
    PAGE_SIMPLE_INSTALL,
    PAGE_CUSTOM1,
    PAGE_CUSTOM2,
    PAGE_MODIFY,
    PAGE_PROGRESS,
    PAGE_PROGRESS_PASSIVE,
    PAGE_SUCCESS,
    PAGE_FAILURE,
    COUNT_PAGE,
};

// This array must be kept in the same order as the PAGE enum.
static LPCWSTR PAGE_NAMES[] = {
    L"Loading",
    L"Help",
    L"Install",
    L"Upgrade",
    L"SimpleInstall",
    L"Custom1",
    L"Custom2",
    L"Modify",
    L"Progress",
    L"ProgressPassive",
    L"Success",
    L"Failure",
};

enum CONTROL_ID {
    // Non-paged controls
    ID_CLOSE_BUTTON = THEME_FIRST_ASSIGN_CONTROL_ID,
    ID_MINIMIZE_BUTTON,

    // Welcome page
    ID_INSTALL_BUTTON,
    ID_INSTALL_CUSTOM_BUTTON,
    ID_INSTALL_SIMPLE_BUTTON,
    ID_INSTALL_UPGRADE_BUTTON,
    ID_INSTALL_UPGRADE_CUSTOM_BUTTON,
    ID_INSTALL_CANCEL_BUTTON,
    ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX,

    // Customize Page
    ID_TARGETDIR_EDITBOX,
    ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX,
    ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX,
    ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX,
    ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL,
    ID_CUSTOM_COMPILE_ALL_CHECKBOX,
    ID_CUSTOM_BROWSE_BUTTON,
    ID_CUSTOM_BROWSE_BUTTON_LABEL,
    ID_CUSTOM_INSTALL_BUTTON,
    ID_CUSTOM_NEXT_BUTTON,
    ID_CUSTOM1_BACK_BUTTON,
    ID_CUSTOM2_BACK_BUTTON,
    ID_CUSTOM1_CANCEL_BUTTON,
    ID_CUSTOM2_CANCEL_BUTTON,

    // Modify page
    ID_MODIFY_BUTTON,
    ID_REPAIR_BUTTON,
    ID_UNINSTALL_BUTTON,
    ID_MODIFY_CANCEL_BUTTON,

    // Progress page
    ID_CACHE_PROGRESS_PACKAGE_TEXT,
    ID_CACHE_PROGRESS_BAR,
    ID_CACHE_PROGRESS_TEXT,

    ID_EXECUTE_PROGRESS_PACKAGE_TEXT,
    ID_EXECUTE_PROGRESS_BAR,
    ID_EXECUTE_PROGRESS_TEXT,
    ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT,

    ID_OVERALL_PROGRESS_PACKAGE_TEXT,
    ID_OVERALL_PROGRESS_BAR,
    ID_OVERALL_CALCULATED_PROGRESS_BAR,
    ID_OVERALL_PROGRESS_TEXT,

    ID_PROGRESS_CANCEL_BUTTON,

    // Success page
    ID_SUCCESS_TEXT,
    ID_SUCCESS_RESTART_TEXT,
    ID_SUCCESS_RESTART_BUTTON,
    ID_SUCCESS_CANCEL_BUTTON,
    ID_SUCCESS_MAX_PATH_BUTTON,

    // Failure page
    ID_FAILURE_LOGFILE_LINK,
    ID_FAILURE_MESSAGE_TEXT,
    ID_FAILURE_RESTART_TEXT,
    ID_FAILURE_RESTART_BUTTON,
    ID_FAILURE_CANCEL_BUTTON
};

static THEME_ASSIGN_CONTROL_ID CONTROL_ID_NAMES[] = {
    { ID_CLOSE_BUTTON, L"CloseButton" },
    { ID_MINIMIZE_BUTTON, L"MinimizeButton" },

    { ID_INSTALL_BUTTON, L"InstallButton" },
    { ID_INSTALL_CUSTOM_BUTTON, L"InstallCustomButton" },
    { ID_INSTALL_SIMPLE_BUTTON, L"InstallSimpleButton" },
    { ID_INSTALL_UPGRADE_BUTTON, L"InstallUpgradeButton" },
    { ID_INSTALL_UPGRADE_CUSTOM_BUTTON, L"InstallUpgradeCustomButton" },
    { ID_INSTALL_CANCEL_BUTTON, L"InstallCancelButton" },
    { ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, L"InstallLauncherAllUsers" },

    { ID_TARGETDIR_EDITBOX, L"TargetDir" },
    { ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, L"AssociateFiles" },
    { ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, L"InstallAllUsers" },
    { ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, L"CustomInstallLauncherAllUsers" },
    { ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL, L"Include_launcherHelp" },
    { ID_CUSTOM_COMPILE_ALL_CHECKBOX, L"CompileAll" },
    { ID_CUSTOM_BROWSE_BUTTON, L"CustomBrowseButton" },
    { ID_CUSTOM_BROWSE_BUTTON_LABEL, L"CustomBrowseButtonLabel" },
    { ID_CUSTOM_INSTALL_BUTTON, L"CustomInstallButton" },
    { ID_CUSTOM_NEXT_BUTTON, L"CustomNextButton" },
    { ID_CUSTOM1_BACK_BUTTON, L"Custom1BackButton" },
    { ID_CUSTOM2_BACK_BUTTON, L"Custom2BackButton" },
    { ID_CUSTOM1_CANCEL_BUTTON, L"Custom1CancelButton" },
    { ID_CUSTOM2_CANCEL_BUTTON, L"Custom2CancelButton" },

    { ID_MODIFY_BUTTON, L"ModifyButton" },
    { ID_REPAIR_BUTTON, L"RepairButton" },
    { ID_UNINSTALL_BUTTON, L"UninstallButton" },
    { ID_MODIFY_CANCEL_BUTTON, L"ModifyCancelButton" },

    { ID_CACHE_PROGRESS_PACKAGE_TEXT, L"CacheProgressPackageText" },
    { ID_CACHE_PROGRESS_BAR, L"CacheProgressbar" },
    { ID_CACHE_PROGRESS_TEXT, L"CacheProgressText" },
    { ID_EXECUTE_PROGRESS_PACKAGE_TEXT, L"ExecuteProgressPackageText" },
    { ID_EXECUTE_PROGRESS_BAR, L"ExecuteProgressbar" },
    { ID_EXECUTE_PROGRESS_TEXT, L"ExecuteProgressText" },
    { ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"ExecuteProgressActionDataText" },
    { ID_OVERALL_PROGRESS_PACKAGE_TEXT, L"OverallProgressPackageText" },
    { ID_OVERALL_PROGRESS_BAR, L"OverallProgressbar" },
    { ID_OVERALL_CALCULATED_PROGRESS_BAR, L"OverallCalculatedProgressbar" },
    { ID_OVERALL_PROGRESS_TEXT, L"OverallProgressText" },
    { ID_PROGRESS_CANCEL_BUTTON, L"ProgressCancelButton" },

    { ID_SUCCESS_TEXT, L"SuccessText" },
    { ID_SUCCESS_RESTART_TEXT, L"SuccessRestartText" },
    { ID_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" },
    { ID_SUCCESS_CANCEL_BUTTON, L"SuccessCancelButton" },
    { ID_SUCCESS_MAX_PATH_BUTTON, L"SuccessMaxPathButton" },

    { ID_FAILURE_LOGFILE_LINK, L"FailureLogFileLink" },
    { ID_FAILURE_MESSAGE_TEXT, L"FailureMessageText" },
    { ID_FAILURE_RESTART_TEXT, L"FailureRestartText" },
    { ID_FAILURE_RESTART_BUTTON, L"FailureRestartButton" },
    { ID_FAILURE_CANCEL_BUTTON, L"FailureCancelButton" },
};

static struct { LPCWSTR regName; LPCWSTR variableName; } OPTIONAL_FEATURES[] = {
    { L"core_d", L"Include_debug" },
    { L"core_pdb", L"Include_symbols" },
    { L"dev", L"Include_dev" },
    { L"doc", L"Include_doc" },
    { L"exe", L"Include_exe" },
    { L"lib", L"Include_lib" },
    { L"path", L"PrependPath" },
    { L"appendpath", L"AppendPath" },
    { L"pip", L"Include_pip" },
    { L"tcltk", L"Include_tcltk" },
    { L"test", L"Include_test" },
    { L"tools", L"Include_tools" },
    { L"Shortcuts", L"Shortcuts" },
    // Include_launcher and AssociateFiles are handled separately and so do
    // not need to be included in this list.
    { nullptr, nullptr }
};



class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
    void ShowPage(DWORD newPageId) {
        // Process each control for special handling in the new page.
        ProcessPageControls(ThemeGetPage(_theme, newPageId));

        // Enable disable controls per-page.
        if (_pageIds[PAGE_INSTALL] == newPageId ||
            _pageIds[PAGE_SIMPLE_INSTALL] == newPageId ||
            _pageIds[PAGE_UPGRADE] == newPageId) {
            InstallPage_Show();
        } else if (_pageIds[PAGE_CUSTOM1] == newPageId) {
            Custom1Page_Show();
        } else if (_pageIds[PAGE_CUSTOM2] == newPageId) {
            Custom2Page_Show();
        } else if (_pageIds[PAGE_MODIFY] == newPageId) {
            ModifyPage_Show();
        } else if (_pageIds[PAGE_SUCCESS] == newPageId) {
            SuccessPage_Show();
        } else if (_pageIds[PAGE_FAILURE] == newPageId) {
            FailurePage_Show();
        }

        // Prevent repainting while switching page to avoid ugly flickering
        _suppressPaint = TRUE;
        ThemeShowPage(_theme, newPageId, SW_SHOW);
        ThemeShowPage(_theme, _visiblePageId, SW_HIDE);
        _suppressPaint = FALSE;
        InvalidateRect(_theme->hwndParent, nullptr, TRUE);
        _visiblePageId = newPageId;

        // On the install page set the focus to the install button or
        // the next enabled control if install is disabled
        if (_pageIds[PAGE_INSTALL] == newPageId) {
            ThemeSetFocus(_theme, ID_INSTALL_BUTTON);
        } else if (_pageIds[PAGE_SIMPLE_INSTALL] == newPageId) {
            ThemeSetFocus(_theme, ID_INSTALL_SIMPLE_BUTTON);
        }
    }

    //
    // Handles control clicks
    //
    void OnCommand(CONTROL_ID id) {
        LPWSTR defaultDir = nullptr;
        LPWSTR targetDir = nullptr;
        LONGLONG elevated, crtInstalled, installAllUsers;
        BOOL checked, launcherChecked;
        WCHAR wzPath[MAX_PATH] = { };
        BROWSEINFOW browseInfo = { };
        PIDLIST_ABSOLUTE pidl = nullptr;
        DWORD pageId;
        HRESULT hr = S_OK;

        switch(id) {
        case ID_CLOSE_BUTTON:
            OnClickCloseButton();
            break;

        // Install commands
        case ID_INSTALL_SIMPLE_BUTTON: __fallthrough;
        case ID_INSTALL_UPGRADE_BUTTON: __fallthrough;
        case ID_INSTALL_BUTTON:
            SavePageSettings();

            hr = BalGetNumericVariable(L"InstallAllUsers", &installAllUsers);
            ExitOnFailure(hr, L"Failed to get install scope");

            hr = _engine->SetVariableNumeric(L"CompileAll", installAllUsers);
            ExitOnFailure(hr, L"Failed to update CompileAll");

            hr = EnsureTargetDir();
            ExitOnFailure(hr, L"Failed to set TargetDir");

            OnPlan(BOOTSTRAPPER_ACTION_INSTALL);
            break;

        case ID_CUSTOM1_BACK_BUTTON:
            SavePageSettings();
            if (_modifying) {
                GoToPage(PAGE_MODIFY);
            } else if (_upgrading) {
                GoToPage(PAGE_UPGRADE);
            } else {
                GoToPage(PAGE_INSTALL);
            }
            break;

        case ID_INSTALL_CUSTOM_BUTTON: __fallthrough;
        case ID_INSTALL_UPGRADE_CUSTOM_BUTTON: __fallthrough;
        case ID_CUSTOM2_BACK_BUTTON:
            SavePageSettings();
            GoToPage(PAGE_CUSTOM1);
            break;

        case ID_CUSTOM_NEXT_BUTTON:
            SavePageSettings();
            GoToPage(PAGE_CUSTOM2);
            break;

        case ID_CUSTOM_INSTALL_BUTTON:
            SavePageSettings();

            hr = EnsureTargetDir();
            ExitOnFailure(hr, L"Failed to set TargetDir");

            hr = BalGetStringVariable(L"TargetDir", &targetDir);
            if (SUCCEEDED(hr)) {
                // TODO: Check whether directory exists and contains another installation
                ReleaseStr(targetDir);
            }

            OnPlan(_command.action);
            break;

        case ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX:
            checked = ThemeIsControlChecked(_theme, ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX);
            _engine->SetVariableNumeric(L"InstallLauncherAllUsers", checked);

            ThemeControlElevates(_theme, ID_INSTALL_BUTTON, WillElevate());
            break;

        case ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX:
            checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX);
            _engine->SetVariableNumeric(L"InstallLauncherAllUsers", checked);

            ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, WillElevate());
            break;

        case ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX:
            checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX);
            _engine->SetVariableNumeric(L"InstallAllUsers", checked);

            ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, WillElevate());
            ThemeControlEnable(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, !checked);
            if (checked) {
                _engine->SetVariableNumeric(L"CompileAll", 1);
                ThemeSendControlMessage(_theme, ID_CUSTOM_COMPILE_ALL_CHECKBOX, BM_SETCHECK, BST_CHECKED, 0);
            }
            ThemeGetTextControl(_theme, ID_TARGETDIR_EDITBOX, &targetDir);
            if (targetDir) {
                // Check the current value against the default to see
                // if we should switch it automatically.
                hr = BalGetStringVariable(
                    checked ? L"DefaultJustForMeTargetDir" : L"DefaultAllUsersTargetDir",
                    &defaultDir
                );
                
                if (SUCCEEDED(hr) && defaultDir) {
                    LPWSTR formatted = nullptr;
                    if (defaultDir[0] && SUCCEEDED(BalFormatString(defaultDir, &formatted))) {
                        if (wcscmp(formatted, targetDir) == 0) {
                            ReleaseStr(defaultDir);
                            defaultDir = nullptr;
                            ReleaseStr(formatted);
                            formatted = nullptr;
                            
                            hr = BalGetStringVariable(
                                checked ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir",
                                &defaultDir
                            );
                            if (SUCCEEDED(hr) && defaultDir && defaultDir[0] && SUCCEEDED(BalFormatString(defaultDir, &formatted))) {
                                ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, formatted);
                                ReleaseStr(formatted);
                            }
                        } else {
                            ReleaseStr(formatted);
                        }
                    }
                    
                    ReleaseStr(defaultDir);
                }
            }
            break;

        case ID_CUSTOM_BROWSE_BUTTON:
            browseInfo.hwndOwner = _hWnd;
            browseInfo.pszDisplayName = wzPath;
            browseInfo.lpszTitle = _theme->sczCaption;
            browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
            pidl = ::SHBrowseForFolderW(&browseInfo);
            if (pidl && ::SHGetPathFromIDListW(pidl, wzPath)) {
                ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, wzPath);
            }

            if (pidl) {
                ::CoTaskMemFree(pidl);
            }
            break;

        // Modify commands
        case ID_MODIFY_BUTTON:
            // Some variables cannot be modified
            _engine->SetVariableString(L"InstallAllUsersState", L"disable");
            _engine->SetVariableString(L"InstallLauncherAllUsersState", L"disable");
            _engine->SetVariableString(L"TargetDirState", L"disable");
            _engine->SetVariableString(L"CustomBrowseButtonState", L"disable");
            _modifying = TRUE;
            GoToPage(PAGE_CUSTOM1);
            break;

        case ID_REPAIR_BUTTON:
            OnPlan(BOOTSTRAPPER_ACTION_REPAIR);
            break;

        case ID_UNINSTALL_BUTTON:
            OnPlan(BOOTSTRAPPER_ACTION_UNINSTALL);
            break;

        case ID_SUCCESS_MAX_PATH_BUTTON:
            EnableMaxPathSupport();
            ThemeControlEnable(_theme, ID_SUCCESS_MAX_PATH_BUTTON, FALSE);
            break;
        }

    LExit:
        return;
    }

    void InstallPage_Show() {
        // Ensure the All Users install button has a UAC shield
        BOOL elevated = WillElevate();
        ThemeControlElevates(_theme, ID_INSTALL_BUTTON, elevated);
        ThemeControlElevates(_theme, ID_INSTALL_SIMPLE_BUTTON, elevated);
        ThemeControlElevates(_theme, ID_INSTALL_UPGRADE_BUTTON, elevated);

        LONGLONG blockedLauncher;
        if (SUCCEEDED(BalGetNumericVariable(L"BlockedLauncher", &blockedLauncher)) && blockedLauncher) {
            LOC_STRING *pLocString = nullptr;
            if (SUCCEEDED(LocGetString(_wixLoc, L"#(loc.ShortInstallLauncherBlockedLabel)", &pLocString)) && pLocString) {
                ThemeSetTextControl(_theme, ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, pLocString->wzText);
            }
        }
    }

    void Custom1Page_Show() {
        LONGLONG installLauncherAllUsers;

        if (FAILED(BalGetNumericVariable(L"InstallLauncherAllUsers", &installLauncherAllUsers))) {
            installLauncherAllUsers = 0;
        }

        ThemeSendControlMessage(_theme, ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, BM_SETCHECK,
            installLauncherAllUsers ? BST_CHECKED : BST_UNCHECKED, 0);

        LOC_STRING *pLocString = nullptr;
        LPCWSTR locKey = L"#(loc.Include_launcherHelp)";
        LONGLONG detectedLauncher;

        if (SUCCEEDED(BalGetNumericVariable(L"DetectedLauncher", &detectedLauncher)) && detectedLauncher) {
            locKey = L"#(loc.Include_launcherRemove)";
        } else if (SUCCEEDED(BalGetNumericVariable(L"DetectedOldLauncher", &detectedLauncher)) && detectedLauncher) {
            locKey = L"#(loc.Include_launcherUpgrade)";
        }

        if (SUCCEEDED(LocGetString(_wixLoc, locKey, &pLocString)) && pLocString) {
            ThemeSetTextControl(_theme, ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL, pLocString->wzText);
        }
    }

    void Custom2Page_Show() {
        HRESULT hr;
        LONGLONG installAll, includeLauncher;
        
        if (FAILED(BalGetNumericVariable(L"InstallAllUsers", &installAll))) {
            installAll = 0;
        }

        if (WillElevate()) {
            ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, TRUE);
            ThemeShowControl(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, SW_HIDE);
        } else {
            ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, FALSE);
            ThemeShowControl(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, SW_SHOW);
        }

        if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) && includeLauncher) {
            ThemeControlEnable(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, TRUE);
        } else {
            ThemeSendControlMessage(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, BM_SETCHECK, BST_UNCHECKED, 0);
            ThemeControlEnable(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, FALSE);
        }

        LPWSTR targetDir = nullptr;
        hr = BalGetStringVariable(L"TargetDir", &targetDir);
        if (SUCCEEDED(hr) && targetDir && targetDir[0]) {
            ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, targetDir);
            StrFree(targetDir);
        } else if (SUCCEEDED(hr)) {
            StrFree(targetDir);
            targetDir = nullptr;

            LPWSTR defaultTargetDir = nullptr;
            hr = BalGetStringVariable(L"DefaultCustomTargetDir", &defaultTargetDir);
            if (SUCCEEDED(hr) && defaultTargetDir && !defaultTargetDir[0]) {
                StrFree(defaultTargetDir);
                defaultTargetDir = nullptr;
                
                hr = BalGetStringVariable(
                    installAll ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir",
                    &defaultTargetDir
                );
            }
            if (SUCCEEDED(hr) && defaultTargetDir) {
                if (defaultTargetDir[0] && SUCCEEDED(BalFormatString(defaultTargetDir, &targetDir))) {
                    ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, targetDir);
                    StrFree(targetDir);
                }
                StrFree(defaultTargetDir);
            }
        }
    }

    void ModifyPage_Show() {
        ThemeControlEnable(_theme, ID_REPAIR_BUTTON, !_suppressRepair);
    }

    void SuccessPage_Show() {
        // on the "Success" page, check if the restart button should be enabled.
        BOOL showRestartButton = FALSE;
        LOC_STRING *successText = nullptr;
        HRESULT hr = S_OK;
        
        if (_restartRequired) {
            if (BOOTSTRAPPER_RESTART_PROMPT == _command.restart) {
                showRestartButton = TRUE;
            }
        }

        switch (_plannedAction) {
        case BOOTSTRAPPER_ACTION_INSTALL:
            hr = LocGetString(_wixLoc, L"#(loc.SuccessInstallMessage)", &successText);
            break;
        case BOOTSTRAPPER_ACTION_MODIFY:
            hr = LocGetString(_wixLoc, L"#(loc.SuccessModifyMessage)", &successText);
            break;
        case BOOTSTRAPPER_ACTION_REPAIR:
            hr = LocGetString(_wixLoc, L"#(loc.SuccessRepairMessage)", &successText);
            break;
        case BOOTSTRAPPER_ACTION_UNINSTALL:
            hr = LocGetString(_wixLoc, L"#(loc.SuccessRemoveMessage)", &successText);
            break;
        }

        if (successText) {
            LPWSTR formattedString = nullptr;
            BalFormatString(successText->wzText, &formattedString);
            if (formattedString) {
                ThemeSetTextControl(_theme, ID_SUCCESS_TEXT, formattedString);
                StrFree(formattedString);
            }
        }

        ThemeControlEnable(_theme, ID_SUCCESS_RESTART_TEXT, showRestartButton);
        ThemeControlEnable(_theme, ID_SUCCESS_RESTART_BUTTON, showRestartButton);

        if (_command.action != BOOTSTRAPPER_ACTION_INSTALL ||
            !IsWindowsVersionOrGreater(10, 0, 0)) {
            ThemeControlEnable(_theme, ID_SUCCESS_MAX_PATH_BUTTON, FALSE);
        } else {
            DWORD dataType = 0, buffer = 0, bufferLen = sizeof(buffer);
            HKEY hKey;
            LRESULT res = RegOpenKeyExW(
                HKEY_LOCAL_MACHINE,
                L"SYSTEM\\CurrentControlSet\\Control\\FileSystem",
                0,
                KEY_READ,
                &hKey
            );
            if (res == ERROR_SUCCESS) {
                res = RegQueryValueExW(hKey, L"LongPathsEnabled", nullptr, &dataType,
                    (LPBYTE)&buffer, &bufferLen);
                RegCloseKey(hKey);
            }
            else {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Failed to open SYSTEM\\CurrentControlSet\\Control\\FileSystem: error code %d", res);
            }
            if (res == ERROR_SUCCESS && dataType == REG_DWORD && buffer == 0) {
                ThemeControlElevates(_theme, ID_SUCCESS_MAX_PATH_BUTTON, TRUE);
            }
            else {
                if (res == ERROR_SUCCESS)
                    BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Failed to read LongPathsEnabled value: error code %d", res);
                else
                    BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Hiding MAX_PATH button because it is already enabled");
                ThemeControlEnable(_theme, ID_SUCCESS_MAX_PATH_BUTTON, FALSE);
            }
        }
    }

    void FailurePage_Show() {
        // on the "Failure" page, show error message and check if the restart button should be enabled.

        // if there is a log file variable then we'll assume the log file exists.
        BOOL showLogLink = (_bundle.sczLogVariable && *_bundle.sczLogVariable);
        BOOL showErrorMessage = FALSE;
        BOOL showRestartButton = FALSE;

        if (FAILED(_hrFinal)) {
            LPWSTR unformattedText = nullptr;
            LPWSTR text = nullptr;

            // If we know the failure message, use that.
            if (_failedMessage && *_failedMessage) {
                StrAllocString(&unformattedText, _failedMessage, 0);
            } else {
                // try to get the error message from the error code.
                StrAllocFromError(&unformattedText, _hrFinal, nullptr);
                if (!unformattedText || !*unformattedText) {
                    StrAllocFromError(&unformattedText, E_FAIL, nullptr);
                }
            }

            if (E_WIXSTDBA_CONDITION_FAILED == _hrFinal) {
                if (unformattedText) {
                    StrAllocString(&text, unformattedText, 0);
                }
            } else {
                StrAllocFormatted(&text, L"0x%08x - %ls", _hrFinal, unformattedText);
            }

            if (text) {
                ThemeSetTextControl(_theme, ID_FAILURE_MESSAGE_TEXT, text);
                showErrorMessage = TRUE;
            }

            ReleaseStr(text);
            ReleaseStr(unformattedText);
        }

        if (_restartRequired && BOOTSTRAPPER_RESTART_PROMPT == _command.restart) {
            showRestartButton = TRUE;
        }

        ThemeControlEnable(_theme, ID_FAILURE_LOGFILE_LINK, showLogLink);
        ThemeControlEnable(_theme, ID_FAILURE_MESSAGE_TEXT, showErrorMessage);
        ThemeControlEnable(_theme, ID_FAILURE_RESTART_TEXT, showRestartButton);
        ThemeControlEnable(_theme, ID_FAILURE_RESTART_BUTTON, showRestartButton);
    }

    static void EnableMaxPathSupport() {
        LPWSTR targetDir = nullptr, defaultDir = nullptr;
        HRESULT hr = BalGetStringVariable(L"TargetDir", &targetDir);
        if (FAILED(hr) || !targetDir || !targetDir[0]) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to get TargetDir");
            return;
        }

        LPWSTR pythonw = nullptr;
        StrAllocFormatted(&pythonw, L"%ls\\pythonw.exe", targetDir);
        if (!pythonw || !pythonw[0]) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to construct pythonw.exe path");
            return;
        }

        LPCWSTR arguments = L"-c \"import winreg; "
            "winreg.SetValueEx("
                "winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, "
                    "r'SYSTEM\\CurrentControlSet\\Control\\FileSystem'), "
                "'LongPathsEnabled', "
                "None, "
                "winreg.REG_DWORD, "
                "1"
            ")\"";
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Executing %ls %ls", pythonw, arguments);
        HINSTANCE res = ShellExecuteW(0, L"runas", pythonw, arguments, NULL, SW_HIDE);
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "return code 0x%08x", res);
    }

public: // IBootstrapperApplication
    virtual STDMETHODIMP OnStartup() {
        HRESULT hr = S_OK;
        DWORD dwUIThreadId = 0;

        // create UI thread
        _hUiThread = ::CreateThread(nullptr, 0, UiThreadProc, this, 0, &dwUIThreadId);
        if (!_hUiThread) {
            ExitWithLastError(hr, "Failed to create UI thread.");
        }

    LExit:
        return hr;
    }


    virtual STDMETHODIMP_(int) OnShutdown() {
        int nResult = IDNOACTION;

        // wait for UI thread to terminate
        if (_hUiThread) {
            ::WaitForSingleObject(_hUiThread, INFINITE);
            ReleaseHandle(_hUiThread);
        }

        // If a restart was required.
        if (_restartRequired && _allowRestart) {
            nResult = IDRESTART;
        }

        return nResult;
    }

    virtual STDMETHODIMP_(int) OnDetectRelatedMsiPackage(
        __in_z LPCWSTR wzPackageId,
        __in_z LPCWSTR /*wzProductCode*/,
        __in BOOL fPerMachine,
        __in DWORD64 /*dw64Version*/,
        __in BOOTSTRAPPER_RELATED_OPERATION operation
    ) {
        // Only check launcher_AllUsers because we'll find the same packages
        // twice if we check launcher_JustForMe as well.
        if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_AllUsers", -1)) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Detected existing launcher install");

            LONGLONG blockedLauncher, detectedLauncher;
            if (FAILED(BalGetNumericVariable(L"BlockedLauncher", &blockedLauncher))) {
                blockedLauncher = 0;
            }

            // Get the prior DetectedLauncher value so we can see if we've
            // detected more than one, and then update the stored variable
            // (we use the original value later on via the local).
            if (FAILED(BalGetNumericVariable(L"DetectedLauncher", &detectedLauncher))) {
                detectedLauncher = 0;
            }
            if (!detectedLauncher) {
                _engine->SetVariableNumeric(L"DetectedLauncher", 1);
            }

            if (blockedLauncher) {
                // Nothing else to do, we're already blocking
            }
            else if (BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE == operation) {
                // Found a higher version, so we can't install ours.
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Higher version launcher has been detected.");
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Launcher will not be installed");
                _engine->SetVariableNumeric(L"BlockedLauncher", 1);
            }
            else if (detectedLauncher) {
                if (!blockedLauncher) {
                    BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Multiple launcher installs have been detected.");
                    BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "No launcher will be installed or upgraded until one has been removed.");
                    _engine->SetVariableNumeric(L"BlockedLauncher", 1);
                }
            }
            else if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation) {
                // Found an older version, so let's run the equivalent as an upgrade
                // This overrides "unknown" all users options, but will leave alone
                // any that have already been set/detected.
                // User can deselect the option to include the launcher, but cannot
                // change it from the current per user/machine setting.
                LONGLONG includeLauncher, includeLauncherAllUsers;
                if (FAILED(BalGetNumericVariable(L"Include_launcher", &includeLauncher))) {
                    includeLauncher = -1;
                }
                if (FAILED(BalGetNumericVariable(L"InstallLauncherAllUsers", &includeLauncherAllUsers))) {
                    includeLauncherAllUsers = -1;
                }

                if (includeLauncher < 0) {
                    _engine->SetVariableNumeric(L"Include_launcher", 1);
                }
                if (includeLauncherAllUsers < 0) {
                    _engine->SetVariableNumeric(L"InstallLauncherAllUsers", fPerMachine ? 1 : 0);
                } else if (includeLauncherAllUsers != fPerMachine ? 1 : 0) {
                    // Requested AllUsers option is inconsistent, so block
                    _engine->SetVariableNumeric(L"BlockedLauncher", 1);
                }
                _engine->SetVariableNumeric(L"DetectedOldLauncher", 1);
            }
        }
        return CheckCanceled() ? IDCANCEL : IDNOACTION;
    }

    virtual STDMETHODIMP_(int) OnDetectRelatedBundle(
        __in LPCWSTR wzBundleId,
        __in BOOTSTRAPPER_RELATION_TYPE relationType,
        __in LPCWSTR /*wzBundleTag*/,
        __in BOOL fPerMachine,
        __in DWORD64 /*dw64Version*/,
        __in BOOTSTRAPPER_RELATED_OPERATION operation
    ) {
        BalInfoAddRelatedBundleAsPackage(&_bundle.packages, wzBundleId, relationType, fPerMachine);

        // Remember when our bundle would cause a downgrade.
        if (BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE == operation) {
            _downgradingOtherVersion = TRUE;
        } else if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Detected previous version - planning upgrade");
            _upgrading = TRUE;

            LoadOptionalFeatureStates(_engine);
        } else if (BOOTSTRAPPER_RELATED_OPERATION_NONE == operation) {
            if (_command.action == BOOTSTRAPPER_ACTION_INSTALL) {
                LOC_STRING *pLocString = nullptr;
                if (SUCCEEDED(LocGetString(_wixLoc, L"#(loc.FailureExistingInstall)", &pLocString)) && pLocString) {
                    BalFormatString(pLocString->wzText, &_failedMessage);
                } else {
                    BalFormatString(L"Cannot install [WixBundleName] because it is already installed.", &_failedMessage);
                }
                BalLog(
                    BOOTSTRAPPER_LOG_LEVEL_ERROR,
                    "Related bundle %ls is preventing install",
                    wzBundleId
                );
                SetState(PYBA_STATE_FAILED, E_WIXSTDBA_CONDITION_FAILED);
            }
        }

        return CheckCanceled() ? IDCANCEL : IDOK;
    }


    virtual STDMETHODIMP_(void) OnDetectPackageComplete(
        __in LPCWSTR wzPackageId,
        __in HRESULT hrStatus,
        __in BOOTSTRAPPER_PACKAGE_STATE state
    ) { }


    virtual STDMETHODIMP_(void) OnDetectComplete(__in HRESULT hrStatus) {
        if (SUCCEEDED(hrStatus) && _baFunction) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect complete BA function");
            _baFunction->OnDetectComplete();
        }

        if (SUCCEEDED(hrStatus)) {
            // Update launcher install states
            // If we didn't detect any existing installs, Include_launcher and
            // InstallLauncherAllUsers will both be -1, so we will set to their
            // defaults and leave the options enabled.
            // Otherwise, if we detected an existing install, we disable the
            // options so they remain fixed.
            // The code in OnDetectRelatedMsiPackage is responsible for figuring
            // out whether existing installs are compatible with the settings in
            // place during detection.
            LONGLONG blockedLauncher;
            if (SUCCEEDED(BalGetNumericVariable(L"BlockedLauncher", &blockedLauncher))
                    && blockedLauncher) {
                _engine->SetVariableNumeric(L"Include_launcher", 0);
                _engine->SetVariableNumeric(L"InstallLauncherAllUsers", 0);
                _engine->SetVariableString(L"InstallLauncherAllUsersState", L"disable");
                _engine->SetVariableString(L"Include_launcherState", L"disable");
            }
            else {
                LONGLONG includeLauncher, includeLauncherAllUsers, associateFiles;

                if (FAILED(BalGetNumericVariable(L"Include_launcher", &includeLauncher))) {
                    includeLauncher = -1;
                }
                if (FAILED(BalGetNumericVariable(L"InstallLauncherAllUsers", &includeLauncherAllUsers))) {
                    includeLauncherAllUsers = -1;
                }
                if (FAILED(BalGetNumericVariable(L"AssociateFiles", &associateFiles))) {
                    associateFiles = -1;
                }

                if (includeLauncherAllUsers < 0) {
                    includeLauncherAllUsers = 0;
                    _engine->SetVariableNumeric(L"InstallLauncherAllUsers", includeLauncherAllUsers);
                }

                if (includeLauncher < 0) {
                    if (BOOTSTRAPPER_ACTION_LAYOUT == _command.action ||
                        (BOOTSTRAPPER_ACTION_INSTALL == _command.action && !_upgrading)) {
                        // When installing/downloading, we include the launcher
                        // (though downloads should ignore this setting anyway)
                        _engine->SetVariableNumeric(L"Include_launcher", 1);
                    } else {
                        // Any other action, we should have detected an existing
                        // install (e.g. on remove/modify), so if we didn't, we
                        // assume it's not selected.
                        _engine->SetVariableNumeric(L"Include_launcher", 0);
                        _engine->SetVariableNumeric(L"AssociateFiles", 0);
                    }
                }

                if (associateFiles < 0) {
                    auto hr = LoadAssociateFilesStateFromKey(
                        _engine,
                        includeLauncherAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER
                    );
                    if (FAILED(hr)) {
                        BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr);
                    } else if (hr == S_OK) {
                        associateFiles = 1;
                    }
                    _engine->SetVariableNumeric(L"AssociateFiles", associateFiles);
                }
            }
        }

        if (SUCCEEDED(hrStatus)) {
            hrStatus = EvaluateConditions();
        }

        if (SUCCEEDED(hrStatus)) {
            // Ensure the default path has been set
            hrStatus = EnsureTargetDir();
        }

        SetState(PYBA_STATE_DETECTED, hrStatus);

        // If we're not interacting with the user or we're doing a layout or we're just after a force restart
        // then automatically start planning.
        if (BOOTSTRAPPER_DISPLAY_FULL > _command.display ||
            BOOTSTRAPPER_ACTION_LAYOUT == _command.action ||
            BOOTSTRAPPER_ACTION_UNINSTALL == _command.action ||
            BOOTSTRAPPER_RESUME_TYPE_REBOOT == _command.resumeType) {
            if (SUCCEEDED(hrStatus)) {
                ::PostMessageW(_hWnd, WM_PYBA_PLAN_PACKAGES, 0, _command.action);
            }
        }
    }


    virtual STDMETHODIMP_(int) OnPlanRelatedBundle(
        __in_z LPCWSTR /*wzBundleId*/,
        __inout_z BOOTSTRAPPER_REQUEST_STATE* pRequestedState
    ) {
        return CheckCanceled() ? IDCANCEL : IDOK;
    }


    virtual STDMETHODIMP_(int) OnPlanPackageBegin(
        __in_z LPCWSTR wzPackageId,
        __inout BOOTSTRAPPER_REQUEST_STATE *pRequestState
    ) {
        HRESULT hr = S_OK;
        BAL_INFO_PACKAGE* pPackage = nullptr;

        if (_nextPackageAfterRestart) {
            // After restart we need to finish the dependency registration for our package so allow the package
            // to go present.
            if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, _nextPackageAfterRestart, -1)) {
                // Do not allow a repair because that could put us in a perpetual restart loop.
                if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == *pRequestState) {
                    *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
                }

                ReleaseNullStr(_nextPackageAfterRestart); // no more skipping now.
            } else {
                // not the matching package, so skip it.
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Skipping package: %ls, after restart because it was applied before the restart.", wzPackageId);

                *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
            }
        } else if ((_plannedAction == BOOTSTRAPPER_ACTION_INSTALL || _plannedAction == BOOTSTRAPPER_ACTION_MODIFY) &&
                   SUCCEEDED(BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage))) {
            BOOL f = FALSE;
            if (SUCCEEDED(_engine->EvaluateCondition(pPackage->sczInstallCondition, &f)) && f) {
                *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
            }
        }

        return CheckCanceled() ? IDCANCEL : IDOK;
    }

    virtual STDMETHODIMP_(int) OnPlanMsiFeature(
        __in_z LPCWSTR wzPackageId,
        __in_z LPCWSTR wzFeatureId,
        __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState
    ) {
        LONGLONG install;
        
        if (wcscmp(wzFeatureId, L"AssociateFiles") == 0 || wcscmp(wzFeatureId, L"Shortcuts") == 0) {
            if (SUCCEEDED(_engine->GetVariableNumeric(wzFeatureId, &install)) && install) {
                *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_LOCAL;
            } else {
                *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_ABSENT;
            }
        } else {
            *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_LOCAL;
        }
        return CheckCanceled() ? IDCANCEL : IDNOACTION;
    }

    virtual STDMETHODIMP_(void) OnPlanComplete(__in HRESULT hrStatus) {
        if (SUCCEEDED(hrStatus) && _baFunction) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running plan complete BA function");
            _baFunction->OnPlanComplete();
        }

        SetState(PYBA_STATE_PLANNED, hrStatus);

        if (SUCCEEDED(hrStatus)) {
            ::PostMessageW(_hWnd, WM_PYBA_APPLY_PACKAGES, 0, 0);
        }

        _startedExecution = FALSE;
        _calculatedCacheProgress = 0;
        _calculatedExecuteProgress = 0;
    }


    virtual STDMETHODIMP_(int) OnCachePackageBegin(
        __in_z LPCWSTR wzPackageId,
        __in DWORD cCachePayloads,
        __in DWORD64 dw64PackageCacheSize
    ) {
        if (wzPackageId && *wzPackageId) {
            BAL_INFO_PACKAGE* pPackage = nullptr;
            HRESULT hr = BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage);
            LPCWSTR wz = (SUCCEEDED(hr) && pPackage->sczDisplayName) ? pPackage->sczDisplayName : wzPackageId;

            ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_PACKAGE_TEXT, wz);

            // If something started executing, leave it in the overall progress text.
            if (!_startedExecution) {
                ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
            }
        }

        return __super::OnCachePackageBegin(wzPackageId, cCachePayloads, dw64PackageCacheSize);
    }


    virtual STDMETHODIMP_(int) OnCacheAcquireProgress(
        __in_z LPCWSTR wzPackageOrContainerId,
        __in_z_opt LPCWSTR wzPayloadId,
        __in DWORD64 dw64Progress,
        __in DWORD64 dw64Total,
        __in DWORD dwOverallPercentage
    ) {
        WCHAR wzProgress[5] = { };

#ifdef DEBUG
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnCacheAcquireProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
#endif

        ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallPercentage);
        ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_TEXT, wzProgress);

        ThemeSetProgressControl(_theme, ID_CACHE_PROGRESS_BAR, dwOverallPercentage);

        _calculatedCacheProgress = dwOverallPercentage * PYBA_ACQUIRE_PERCENTAGE / 100;
        ThemeSetProgressControl(_theme, ID_OVERALL_CALCULATED_PROGRESS_BAR, _calculatedCacheProgress + _calculatedExecuteProgress);

        SetTaskbarButtonProgress(_calculatedCacheProgress + _calculatedExecuteProgress);

        return __super::OnCacheAcquireProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
    }


    virtual STDMETHODIMP_(int) OnCacheAcquireComplete(
        __in_z LPCWSTR wzPackageOrContainerId,
        __in_z_opt LPCWSTR wzPayloadId,
        __in HRESULT hrStatus,
        __in int nRecommendation
    ) {
        SetProgressState(hrStatus);
        return __super::OnCacheAcquireComplete(wzPackageOrContainerId, wzPayloadId, hrStatus, nRecommendation);
    }


    virtual STDMETHODIMP_(int) OnCacheVerifyComplete(
        __in_z LPCWSTR wzPackageId,
        __in_z LPCWSTR wzPayloadId,
        __in HRESULT hrStatus,
        __in int nRecommendation
    ) {
        SetProgressState(hrStatus);
        return __super::OnCacheVerifyComplete(wzPackageId, wzPayloadId, hrStatus, nRecommendation);
    }


    virtual STDMETHODIMP_(void) OnCacheComplete(__in HRESULT /*hrStatus*/) {
        ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_PACKAGE_TEXT, L"");
        SetState(PYBA_STATE_CACHED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
    }


    virtual STDMETHODIMP_(int) OnError(
        __in BOOTSTRAPPER_ERROR_TYPE errorType,
        __in LPCWSTR wzPackageId,
        __in DWORD dwCode,
        __in_z LPCWSTR wzError,
        __in DWORD dwUIHint,
        __in DWORD /*cData*/,
        __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/,
        __in int nRecommendation
    ) {
        int nResult = nRecommendation;
        LPWSTR sczError = nullptr;

        if (BOOTSTRAPPER_DISPLAY_EMBEDDED == _command.display) {
            HRESULT hr = _engine->SendEmbeddedError(dwCode, wzError, dwUIHint, &nResult);
            if (FAILED(hr)) {
                nResult = IDERROR;
            }
        } else if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) {
            // If this is an authentication failure, let the engine try to handle it for us.
            if (BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_SERVER == errorType || BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_PROXY == errorType) {
                nResult = IDTRYAGAIN;
            } else // show a generic error message box.
            {
                BalRetryErrorOccurred(wzPackageId, dwCode);

                if (!_showingInternalUIThisPackage) {
                    // If no error message was provided, use the error code to try and get an error message.
                    if (!wzError || !*wzError || BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER != errorType) {
                        HRESULT hr = StrAllocFromError(&sczError, dwCode, nullptr);
                        if (FAILED(hr) || !sczError || !*sczError) {
                            StrAllocFormatted(&sczError, L"0x%x", dwCode);
                        }
                    }

                    nResult = ::MessageBoxW(_hWnd, sczError ? sczError : wzError, _theme->sczCaption, dwUIHint);
                }
            }

            SetProgressState(HRESULT_FROM_WIN32(dwCode));
        } else {
            // just take note of the error code and let things continue.
            BalRetryErrorOccurred(wzPackageId, dwCode);
        }

        ReleaseStr(sczError);
        return nResult;
    }


    virtual STDMETHODIMP_(int) OnExecuteMsiMessage(
        __in_z LPCWSTR wzPackageId,
        __in INSTALLMESSAGE mt,
        __in UINT uiFlags,
        __in_z LPCWSTR wzMessage,
        __in DWORD cData,
        __in_ecount_z_opt(cData) LPCWSTR* rgwzData,
        __in int nRecommendation
    ) {
#ifdef DEBUG
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnExecuteMsiMessage() - package: %ls, message: %ls", wzPackageId, wzMessage);
#endif
        if (BOOTSTRAPPER_DISPLAY_FULL == _command.display && (INSTALLMESSAGE_WARNING == mt || INSTALLMESSAGE_USER == mt)) {
            int nResult = ::MessageBoxW(_hWnd, wzMessage, _theme->sczCaption, uiFlags);
            return nResult;
        }

        if (INSTALLMESSAGE_ACTIONSTART == mt) {
            ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, wzMessage);
        }

        return __super::OnExecuteMsiMessage(wzPackageId, mt, uiFlags, wzMessage, cData, rgwzData, nRecommendation);
    }


    virtual STDMETHODIMP_(int) OnProgress(__in DWORD dwProgressPercentage, __in DWORD dwOverallProgressPercentage) {
        WCHAR wzProgress[5] = { };

#ifdef DEBUG
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnProgress() - progress: %u%%, overall progress: %u%%", dwProgressPercentage, dwOverallProgressPercentage);
#endif

        ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
        ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_TEXT, wzProgress);

        ThemeSetProgressControl(_theme, ID_OVERALL_PROGRESS_BAR, dwOverallProgressPercentage);
        SetTaskbarButtonProgress(dwOverallProgressPercentage);

        return __super::OnProgress(dwProgressPercentage, dwOverallProgressPercentage);
    }


    virtual STDMETHODIMP_(int) OnExecutePackageBegin(__in_z LPCWSTR wzPackageId, __in BOOL fExecute) {
        LPWSTR sczFormattedString = nullptr;

        _startedExecution = TRUE;

        if (wzPackageId && *wzPackageId) {
            BAL_INFO_PACKAGE* pPackage = nullptr;
            BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage);

            LPCWSTR wz = wzPackageId;
            if (pPackage) {
                LOC_STRING* pLocString = nullptr;

                switch (pPackage->type) {
                case BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON:
                    LocGetString(_wixLoc, L"#(loc.ExecuteAddonRelatedBundleMessage)", &pLocString);
                    break;

                case BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH:
                    LocGetString(_wixLoc, L"#(loc.ExecutePatchRelatedBundleMessage)", &pLocString);
                    break;

                case BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE:
                    LocGetString(_wixLoc, L"#(loc.ExecuteUpgradeRelatedBundleMessage)", &pLocString);
                    break;
                }

                if (pLocString) {
                    // If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe
                    // so don't go down the rabbit hole of making sure that this is securely freed.
                    BalFormatString(pLocString->wzText, &sczFormattedString);
                }

                wz = sczFormattedString ? sczFormattedString : pPackage->sczDisplayName ? pPackage->sczDisplayName : wzPackageId;
            }

            _showingInternalUIThisPackage = pPackage && pPackage->fDisplayInternalUI;

            ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_PACKAGE_TEXT, wz);
            ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
        } else {
            _showingInternalUIThisPackage = FALSE;
        }

        ReleaseStr(sczFormattedString);
        return __super::OnExecutePackageBegin(wzPackageId, fExecute);
    }


    virtual int __stdcall OnExecuteProgress(
        __in_z LPCWSTR wzPackageId,
        __in DWORD dwProgressPercentage,
        __in DWORD dwOverallProgressPercentage
    ) {
        WCHAR wzProgress[8] = { };

#ifdef DEBUG
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnExecuteProgress() - package: %ls, progress: %u%%, overall progress: %u%%", wzPackageId, dwProgressPercentage, dwOverallProgressPercentage);
#endif

        ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
        ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_TEXT, wzProgress);

        ThemeSetProgressControl(_theme, ID_EXECUTE_PROGRESS_BAR, dwOverallProgressPercentage);

        _calculatedExecuteProgress = dwOverallProgressPercentage * (100 - PYBA_ACQUIRE_PERCENTAGE) / 100;
        ThemeSetProgressControl(_theme, ID_OVERALL_CALCULATED_PROGRESS_BAR, _calculatedCacheProgress + _calculatedExecuteProgress);

        SetTaskbarButtonProgress(_calculatedCacheProgress + _calculatedExecuteProgress);

        return __super::OnExecuteProgress(wzPackageId, dwProgressPercentage, dwOverallProgressPercentage);
    }


    virtual STDMETHODIMP_(int) OnExecutePackageComplete(
        __in_z LPCWSTR wzPackageId,
        __in HRESULT hrExitCode,
        __in BOOTSTRAPPER_APPLY_RESTART restart,
        __in int nRecommendation
    ) {
        SetProgressState(hrExitCode);

        if (_wcsnicmp(wzPackageId, L"path_", 5) == 0 && SUCCEEDED(hrExitCode)) {
            SendMessageTimeoutW(
                HWND_BROADCAST,
                WM_SETTINGCHANGE,
                0,
                reinterpret_cast<LPARAM>(L"Environment"),
                SMTO_ABORTIFHUNG,
                1000,
                nullptr
            );
        }

        int nResult = __super::OnExecutePackageComplete(wzPackageId, hrExitCode, restart, nRecommendation);

        return nResult;
    }


    virtual STDMETHODIMP_(void) OnExecuteComplete(__in HRESULT hrStatus) {
        ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_PACKAGE_TEXT, L"");
        ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"");
        ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, L"");
        ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, FALSE); // no more cancel.

        SetState(PYBA_STATE_EXECUTED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
        SetProgressState(hrStatus);
    }


    virtual STDMETHODIMP_(int) OnResolveSource(
        __in_z LPCWSTR wzPackageOrContainerId,
        __in_z_opt LPCWSTR wzPayloadId,
        __in_z LPCWSTR wzLocalSource,
        __in_z_opt LPCWSTR wzDownloadSource
    ) {
        int nResult = IDERROR; // assume we won't resolve source and that is unexpected.

        if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) {
            if (wzDownloadSource) {
                nResult = IDDOWNLOAD;
            } else {
                // prompt to change the source location.
                OPENFILENAMEW ofn = { };
                WCHAR wzFile[MAX_PATH] = { };

                ::StringCchCopyW(wzFile, countof(wzFile), wzLocalSource);

                ofn.lStructSize = sizeof(ofn);
                ofn.hwndOwner = _hWnd;
                ofn.lpstrFile = wzFile;
                ofn.nMaxFile = countof(wzFile);
                ofn.lpstrFilter = L"All Files\0*.*\0";
                ofn.nFilterIndex = 1;
                ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
                ofn.lpstrTitle = _theme->sczCaption;

                if (::GetOpenFileNameW(&ofn)) {
                    HRESULT hr = _engine->SetLocalSource(wzPackageOrContainerId, wzPayloadId, ofn.lpstrFile);
                    nResult = SUCCEEDED(hr) ? IDRETRY : IDERROR;
                } else {
                    nResult = IDCANCEL;
                }
            }
        } else if (wzDownloadSource) {
            // If doing a non-interactive install and download source is available, let's try downloading the package silently
            nResult = IDDOWNLOAD;
        }
        // else there's nothing more we can do in non-interactive mode

        return CheckCanceled() ? IDCANCEL : nResult;
    }


    virtual STDMETHODIMP_(int) OnApplyComplete(__in HRESULT hrStatus, __in BOOTSTRAPPER_APPLY_RESTART restart) {
        _restartResult = restart; // remember the restart result so we return the correct error code no matter what the user chooses to do in the UI.

        // If a restart was encountered and we are not suppressing restarts, then restart is required.
        _restartRequired = (BOOTSTRAPPER_APPLY_RESTART_NONE != restart && BOOTSTRAPPER_RESTART_NEVER < _command.restart);
        // If a restart is required and we're not displaying a UI or we are not supposed to prompt for restart then allow the restart.
        _allowRestart = _restartRequired && (BOOTSTRAPPER_DISPLAY_FULL > _command.display || BOOTSTRAPPER_RESTART_PROMPT < _command.restart);

        // If we are showing UI, wait a beat before moving to the final screen.
        if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) {
            ::Sleep(250);
        }

        SetState(PYBA_STATE_APPLIED, hrStatus);
        SetTaskbarButtonProgress(100); // show full progress bar, green, yellow, or red

        return IDNOACTION;
    }

    virtual STDMETHODIMP_(void) OnLaunchApprovedExeComplete(__in HRESULT hrStatus, __in DWORD /*processId*/) {
    }


private:
    //
    // UiThreadProc - entrypoint for UI thread.
    //
    static DWORD WINAPI UiThreadProc(__in LPVOID pvContext) {
        HRESULT hr = S_OK;
        PythonBootstrapperApplication* pThis = (PythonBootstrapperApplication*)pvContext;
        BOOL comInitialized = FALSE;
        BOOL ret = FALSE;
        MSG msg = { };

        // Initialize COM and theme.
        hr = ::CoInitialize(nullptr);
        BalExitOnFailure(hr, "Failed to initialize COM.");
        comInitialized = TRUE;

        hr = ThemeInitialize(pThis->_hModule);
        BalExitOnFailure(hr, "Failed to initialize theme manager.");

        hr = pThis->InitializeData();
        BalExitOnFailure(hr, "Failed to initialize data in bootstrapper application.");

        // Create main window.
        pThis->InitializeTaskbarButton();
        hr = pThis->CreateMainWindow();
        BalExitOnFailure(hr, "Failed to create main window.");

        pThis->ValidateOperatingSystem();

        if (FAILED(pThis->_hrFinal)) {
            pThis->SetState(PYBA_STATE_FAILED, hr);
            ::PostMessageW(pThis->_hWnd, WM_PYBA_SHOW_FAILURE, 0, 0);
        } else {
            // Okay, we're ready for packages now.
            pThis->SetState(PYBA_STATE_INITIALIZED, hr);
            ::PostMessageW(pThis->_hWnd, BOOTSTRAPPER_ACTION_HELP == pThis->_command.action ? WM_PYBA_SHOW_HELP : WM_PYBA_DETECT_PACKAGES, 0, 0);
        }

        // message pump
        while (0 != (ret = ::GetMessageW(&msg, nullptr, 0, 0))) {
            if (-1 == ret) {
                hr = E_UNEXPECTED;
                BalExitOnFailure(hr, "Unexpected return value from message pump.");
            } else if (!ThemeHandleKeyboardMessage(pThis->_theme, msg.hwnd, &msg)) {
                ::TranslateMessage(&msg);
                ::DispatchMessageW(&msg);
            }
        }

        // Succeeded thus far, check to see if anything went wrong while actually
        // executing changes.
        if (FAILED(pThis->_hrFinal)) {
            hr = pThis->_hrFinal;
        } else if (pThis->CheckCanceled()) {
            hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
        }

    LExit:
        // destroy main window
        pThis->DestroyMainWindow();

        // initiate engine shutdown
        DWORD dwQuit = HRESULT_CODE(hr);
        if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->_restartResult) {
            dwQuit = ERROR_SUCCESS_REBOOT_INITIATED;
        } else if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == pThis->_restartResult) {
            dwQuit = ERROR_SUCCESS_REBOOT_REQUIRED;
        }
        pThis->_engine->Quit(dwQuit);

        ReleaseTheme(pThis->_theme);
        ThemeUninitialize();

        // uninitialize COM
        if (comInitialized) {
            ::CoUninitialize();
        }

        return hr;
    }

    //
    // ParseVariablesFromUnattendXml - reads options from unattend.xml if it
    // exists
    //
    HRESULT ParseVariablesFromUnattendXml() {
        HRESULT hr = S_OK;
        LPWSTR sczUnattendXmlPath = nullptr;
        IXMLDOMDocument *pixdUnattend = nullptr;
        IXMLDOMNodeList *pNodes = nullptr;
        IXMLDOMNode *pNode = nullptr;
        long cNodes;
        DWORD dwAttr;
        LPWSTR scz = nullptr;
        BOOL bValue;
        int iValue;
        BOOL tryConvert;
        BSTR bstrValue = nullptr;

        hr = BalFormatString(L"[WixBundleOriginalSourceFolder]unattend.xml", &sczUnattendXmlPath);
        BalExitOnFailure(hr, "Failed to calculate path to unattend.xml");

        if (!FileExistsEx(sczUnattendXmlPath, &dwAttr)) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Did not find %ls", sczUnattendXmlPath);
            hr = S_FALSE;
            goto LExit;
        }

        hr = XmlLoadDocumentFromFile(sczUnattendXmlPath, &pixdUnattend);
        BalExitOnFailure1(hr, "Failed to read %ls", sczUnattendXmlPath);

        // get the list of variables users have overridden
        hr = XmlSelectNodes(pixdUnattend, L"/Options/Option", &pNodes);
        if (S_FALSE == hr) {
            ExitFunction1(hr = S_OK);
        }
        BalExitOnFailure(hr, "Failed to select option nodes.");

        hr = pNodes->get_length((long*)&cNodes);
        BalExitOnFailure(hr, "Failed to get option node count.");

        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Reading settings from %ls", sczUnattendXmlPath);

        for (DWORD i = 0; i < cNodes; ++i) {
            hr = XmlNextElement(pNodes, &pNode, nullptr);
            BalExitOnFailure(hr, "Failed to get next node.");

            // @Name
            hr = XmlGetAttributeEx(pNode, L"Name", &scz);
            BalExitOnFailure(hr, "Failed to get @Name.");

            tryConvert = TRUE;
            hr = XmlGetAttribute(pNode, L"Value", &bstrValue);
            if (FAILED(hr) || !bstrValue || !*bstrValue) {
                hr = XmlGetText(pNode, &bstrValue);
                tryConvert = FALSE;
            }
            BalExitOnFailure(hr, "Failed to get @Value.");

            if (tryConvert &&
                CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, bstrValue, -1, L"yes", -1)) {
                _engine->SetVariableNumeric(scz, 1);
            } else if (tryConvert &&
                       CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, bstrValue, -1, L"no", -1)) {
                _engine->SetVariableNumeric(scz, 0);
            } else if (tryConvert && ::StrToIntExW(bstrValue, STIF_DEFAULT, &iValue)) {
                _engine->SetVariableNumeric(scz, iValue);
            } else {
                _engine->SetVariableString(scz, bstrValue);
            }

            ReleaseNullBSTR(bstrValue);
            ReleaseNullStr(scz);
            ReleaseNullObject(pNode);
        }

        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Finished reading from %ls", sczUnattendXmlPath);

    LExit:
        ReleaseObject(pNode);
        ReleaseObject(pNodes);
        ReleaseObject(pixdUnattend);
        ReleaseStr(sczUnattendXmlPath);

        return hr;
    }


    //
    // InitializeData - initializes all the package information.
    //
    HRESULT InitializeData() {
        HRESULT hr = S_OK;
        LPWSTR sczModulePath = nullptr;
        IXMLDOMDocument *pixdManifest = nullptr;

        hr = BalManifestLoad(_hModule, &pixdManifest);
        BalExitOnFailure(hr, "Failed to load bootstrapper application manifest.");

        hr = ParseOverridableVariablesFromXml(pixdManifest);
        BalExitOnFailure(hr, "Failed to read overridable variables.");

        if (_command.action == BOOTSTRAPPER_ACTION_MODIFY) {
            LoadOptionalFeatureStates(_engine);
        }

        hr = ParseVariablesFromUnattendXml();
        ExitOnFailure(hr, "Failed to read unattend.ini file.");

        hr = ProcessCommandLine(&_language);
        ExitOnFailure(hr, "Unknown commandline parameters.");

        hr = PathRelativeToModule(&sczModulePath, nullptr, _hModule);
        BalExitOnFailure(hr, "Failed to get module path.");

        hr = LoadLocalization(sczModulePath, _language);
        ExitOnFailure(hr, "Failed to load localization.");

        hr = LoadTheme(sczModulePath, _language);
        ExitOnFailure(hr, "Failed to load theme.");

        hr = BalInfoParseFromXml(&_bundle, pixdManifest);
        BalExitOnFailure(hr, "Failed to load bundle information.");

        hr = BalConditionsParseFromXml(&_conditions, pixdManifest, _wixLoc);
        BalExitOnFailure(hr, "Failed to load conditions from XML.");

        hr = LoadBootstrapperBAFunctions();
        BalExitOnFailure(hr, "Failed to load bootstrapper functions.");

        hr = UpdateUIStrings(_command.action);
        BalExitOnFailure(hr, "Failed to load UI strings.");

        GetBundleFileVersion();
        // don't fail if we couldn't get the version info; best-effort only
    LExit:
        ReleaseObject(pixdManifest);
        ReleaseStr(sczModulePath);

        return hr;
    }


    //
    // ProcessCommandLine - process the provided command line arguments.
    //
    HRESULT ProcessCommandLine(__inout LPWSTR* psczLanguage) {
        HRESULT hr = S_OK;
        int argc = 0;
        LPWSTR* argv = nullptr;
        LPWSTR sczVariableName = nullptr;
        LPWSTR sczVariableValue = nullptr;

        if (_command.wzCommandLine && *_command.wzCommandLine) {
            argv = ::CommandLineToArgvW(_command.wzCommandLine, &argc);
            ExitOnNullWithLastError(argv, hr, "Failed to get command line.");

            for (int i = 0; i < argc; ++i) {
                if (argv[i][0] == L'-' || argv[i][0] == L'/') {
                    if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"lang", -1)) {
                        if (i + 1 >= argc) {
                            hr = E_INVALIDARG;
                            BalExitOnFailure(hr, "Must specify a language.");
                        }

                        ++i;

                        hr = StrAllocString(psczLanguage, &argv[i][0], 0);
                        BalExitOnFailure(hr, "Failed to copy language.");
                    } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"simple", -1)) {
                        _engine->SetVariableNumeric(L"SimpleInstall", 1);
                    }
                } else if (_overridableVariables) {
                    int value;
                    const wchar_t* pwc = wcschr(argv[i], L'=');
                    if (pwc) {
                        hr = StrAllocString(&sczVariableName, argv[i], pwc - argv[i]);
                        BalExitOnFailure(hr, "Failed to copy variable name.");

                        hr = DictKeyExists(_overridableVariables, sczVariableName);
                        if (E_NOTFOUND == hr) {
                            BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to set non-overridable variable: '%ls'.", sczVariableName);
                            hr = S_OK;
                            continue;
                        }
                        ExitOnFailure(hr, "Failed to check the dictionary of overridable variables.");

                        hr = StrAllocString(&sczVariableValue, ++pwc, 0);
                        BalExitOnFailure(hr, "Failed to copy variable value.");

                        if (::StrToIntEx(sczVariableValue, STIF_DEFAULT, &value)) {
                            hr = _engine->SetVariableNumeric(sczVariableName, value);
                        } else {
                            hr = _engine->SetVariableString(sczVariableName, sczVariableValue);
                        }
                        BalExitOnFailure(hr, "Failed to set variable.");
                    } else {
                        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Ignoring unknown argument: %ls", argv[i]);
                    }
                }
            }
        }

    LExit:
        if (argv) {
            ::LocalFree(argv);
        }

        ReleaseStr(sczVariableName);
        ReleaseStr(sczVariableValue);

        return hr;
    }

    HRESULT LoadLocalization(__in_z LPCWSTR wzModulePath, __in_z_opt LPCWSTR wzLanguage) {
        HRESULT hr = S_OK;
        LPWSTR sczLocPath = nullptr;
        LPCWSTR wzLocFileName = L"Default.wxl";

        hr = LocProbeForFile(wzModulePath, wzLocFileName, wzLanguage, &sczLocPath);
        BalExitOnFailure2(hr, "Failed to probe for loc file: %ls in path: %ls", wzLocFileName, wzModulePath);

        hr = LocLoadFromFile(sczLocPath, &_wixLoc);
        BalExitOnFailure1(hr, "Failed to load loc file from path: %ls", sczLocPath);

        if (WIX_LOCALIZATION_LANGUAGE_NOT_SET != _wixLoc->dwLangId) {
            ::SetThreadLocale(_wixLoc->dwLangId);
        }

        hr = StrAllocString(&_confirmCloseMessage, L"#(loc.ConfirmCancelMessage)", 0);
        ExitOnFailure(hr, "Failed to initialize confirm message loc identifier.");

        hr = LocLocalizeString(_wixLoc, &_confirmCloseMessage);
        BalExitOnFailure1(hr, "Failed to localize confirm close message: %ls", _confirmCloseMessage);

    LExit:
        ReleaseStr(sczLocPath);

        return hr;
    }


    HRESULT LoadTheme(__in_z LPCWSTR wzModulePath, __in_z_opt LPCWSTR wzLanguage) {
        HRESULT hr = S_OK;
        LPWSTR sczThemePath = nullptr;
        LPCWSTR wzThemeFileName = L"Default.thm";
        LPWSTR sczCaption = nullptr;

        hr = LocProbeForFile(wzModulePath, wzThemeFileName, wzLanguage, &sczThemePath);
        BalExitOnFailure2(hr, "Failed to probe for theme file: %ls in path: %ls", wzThemeFileName, wzModulePath);

        hr = ThemeLoadFromFile(sczThemePath, &_theme);
        BalExitOnFailure1(hr, "Failed to load theme from path: %ls", sczThemePath);

        hr = ThemeLocalize(_theme, _wixLoc);
        BalExitOnFailure1(hr, "Failed to localize theme: %ls", sczThemePath);

        // Update the caption if there are any formatted strings in it.
        // If the wix developer is showing a hidden variable in the UI, then
        // obviously they don't care about keeping it safe so don't go down the
        // rabbit hole of making sure that this is securely freed.
        hr = BalFormatString(_theme->sczCaption, &sczCaption);
        if (SUCCEEDED(hr)) {
            ThemeUpdateCaption(_theme, sczCaption);
        }

    LExit:
        ReleaseStr(sczCaption);
        ReleaseStr(sczThemePath);

        return hr;
    }


    HRESULT ParseOverridableVariablesFromXml(__in IXMLDOMDocument* pixdManifest) {
        HRESULT hr = S_OK;
        IXMLDOMNode* pNode = nullptr;
        IXMLDOMNodeList* pNodes = nullptr;
        DWORD cNodes = 0;
        LPWSTR scz = nullptr;
        BOOL hidden = FALSE;

        // get the list of variables users can override on the command line
        hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOverridableVariable", &pNodes);
        if (S_FALSE == hr) {
            ExitFunction1(hr = S_OK);
        }
        ExitOnFailure(hr, "Failed to select overridable variable nodes.");

        hr = pNodes->get_length((long*)&cNodes);
        ExitOnFailure(hr, "Failed to get overridable variable node count.");

        if (cNodes) {
            hr = DictCreateStringList(&_overridableVariables, 32, DICT_FLAG_NONE);
            ExitOnFailure(hr, "Failed to create the string dictionary.");

            for (DWORD i = 0; i < cNodes; ++i) {
                hr = XmlNextElement(pNodes, &pNode, nullptr);
                ExitOnFailure(hr, "Failed to get next node.");

                // @Name
                hr = XmlGetAttributeEx(pNode, L"Name", &scz);
                ExitOnFailure(hr, "Failed to get @Name.");

                hr = XmlGetYesNoAttribute(pNode, L"Hidden", &hidden);

                if (!hidden) {
                    hr = DictAddKey(_overridableVariables, scz);
                    ExitOnFailure1(hr, "Failed to add \"%ls\" to the string dictionary.", scz);
                }

                // prepare next iteration
                ReleaseNullObject(pNode);
            }
        }

    LExit:
        ReleaseObject(pNode);
        ReleaseObject(pNodes);
        ReleaseStr(scz);
        return hr;
    }


    //
    // Get the file version of the bootstrapper and record in bootstrapper log file
    //
    HRESULT GetBundleFileVersion() {
        HRESULT hr = S_OK;
        ULARGE_INTEGER uliVersion = { };
        LPWSTR sczCurrentPath = nullptr;

        hr = PathForCurrentProcess(&sczCurrentPath, nullptr);
        BalExitOnFailure(hr, "Failed to get bundle path.");

        hr = FileVersion(sczCurrentPath, &uliVersion.HighPart, &uliVersion.LowPart);
        BalExitOnFailure(hr, "Failed to get bundle file version.");

        hr = _engine->SetVariableVersion(PYBA_VARIABLE_BUNDLE_FILE_VERSION, uliVersion.QuadPart);
        BalExitOnFailure(hr, "Failed to set WixBundleFileVersion variable.");

    LExit:
        ReleaseStr(sczCurrentPath);

        return hr;
    }


    //
    // CreateMainWindow - creates the main install window.
    //
    HRESULT CreateMainWindow() {
        HRESULT hr = S_OK;
        HICON hIcon = reinterpret_cast<HICON>(_theme->hIcon);
        WNDCLASSW wc = { };
        DWORD dwWindowStyle = 0;
        int x = CW_USEDEFAULT;
        int y = CW_USEDEFAULT;
        POINT ptCursor = { };
        HMONITOR hMonitor = nullptr;
        MONITORINFO mi = { };
        COLORREF fg, bg;
        HBRUSH bgBrush;

        // If the theme did not provide an icon, try using the icon from the bundle engine.
        if (!hIcon) {
            HMODULE hBootstrapperEngine = ::GetModuleHandleW(nullptr);
            if (hBootstrapperEngine) {
                hIcon = ::LoadIconW(hBootstrapperEngine, MAKEINTRESOURCEW(1));
            }
        }

        fg = RGB(0, 0, 0);
        bg = RGB(255, 255, 255);
        bgBrush = (HBRUSH)(COLOR_WINDOW+1);
        if (_theme->dwFontId < _theme->cFonts) {
            THEME_FONT *font = &_theme->rgFonts[_theme->dwFontId];
            fg = font->crForeground;
            bg = font->crBackground;
            bgBrush = font->hBackground;
            RemapColor(&fg, &bg, &bgBrush);
        }

        // Register the window class and create the window.
        wc.lpfnWndProc = PythonBootstrapperApplication::WndProc;
        wc.hInstance = _hModule;
        wc.hIcon = hIcon;
        wc.hCursor = ::LoadCursorW(nullptr, (LPCWSTR)IDC_ARROW);
        wc.hbrBackground = bgBrush;
        wc.lpszMenuName = nullptr;
        wc.lpszClassName = PYBA_WINDOW_CLASS;
        if (!::RegisterClassW(&wc)) {
            ExitWithLastError(hr, "Failed to register window.");
        }

        _registered = TRUE;

        // Calculate the window style based on the theme style and command display value.
        dwWindowStyle = _theme->dwStyle;
        if (BOOTSTRAPPER_DISPLAY_NONE >= _command.display) {
            dwWindowStyle &= ~WS_VISIBLE;
        }

        // Don't show the window if there is a splash screen (it will be made visible when the splash screen is hidden)
        if (::IsWindow(_command.hwndSplashScreen)) {
            dwWindowStyle &= ~WS_VISIBLE;
        }

        // Center the window on the monitor with the mouse.
        if (::GetCursorPos(&ptCursor)) {
            hMonitor = ::MonitorFromPoint(ptCursor, MONITOR_DEFAULTTONEAREST);
            if (hMonitor) {
                mi.cbSize = sizeof(mi);
                if (::GetMonitorInfoW(hMonitor, &mi)) {
                    x = mi.rcWork.left + (mi.rcWork.right - mi.rcWork.left - _theme->nWidth) / 2;
                    y = mi.rcWork.top + (mi.rcWork.bottom - mi.rcWork.top - _theme->nHeight) / 2;
                }
            }
        }

        _hWnd = ::CreateWindowExW(
            0,
            wc.lpszClassName,
            _theme->sczCaption,
            dwWindowStyle,
            x,
            y,
            _theme->nWidth,
            _theme->nHeight,
            HWND_DESKTOP,
            nullptr,
            _hModule,
            this
        );
        ExitOnNullWithLastError(_hWnd, hr, "Failed to create window.");

        hr = S_OK;

    LExit:
        return hr;
    }


    //
    // InitializeTaskbarButton - initializes taskbar button for progress.
    //
    void InitializeTaskbarButton() {
        HRESULT hr = S_OK;

        hr = ::CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, __uuidof(ITaskbarList3), reinterpret_cast<LPVOID*>(&_taskbarList));
        if (REGDB_E_CLASSNOTREG == hr) {
            // not supported before Windows 7
            ExitFunction1(hr = S_OK);
        }
        BalExitOnFailure(hr, "Failed to create ITaskbarList3. Continuing.");

        _taskbarButtonCreatedMessage = ::RegisterWindowMessageW(L"TaskbarButtonCreated");
        BalExitOnNullWithLastError(_taskbarButtonCreatedMessage, hr, "Failed to get TaskbarButtonCreated message. Continuing.");

    LExit:
        return;
    }

    //
    // DestroyMainWindow - clean up all the window registration.
    //
    void DestroyMainWindow() {
        if (::IsWindow(_hWnd)) {
            ::DestroyWindow(_hWnd);
            _hWnd = nullptr;
            _taskbarButtonOK = FALSE;
        }

        if (_registered) {
            ::UnregisterClassW(PYBA_WINDOW_CLASS, _hModule);
            _registered = FALSE;
        }
    }


    //
    // WndProc - standard windows message handler.
    //
    static LRESULT CALLBACK WndProc(
        __in HWND hWnd,
        __in UINT uMsg,
        __in WPARAM wParam,
        __in LPARAM lParam
    ) {
#pragma warning(suppress:4312)
        auto pBA = reinterpret_cast<PythonBootstrapperApplication*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));

        switch (uMsg) {
        case WM_NCCREATE: {
            LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
            pBA = reinterpret_cast<PythonBootstrapperApplication*>(lpcs->lpCreateParams);
#pragma warning(suppress:4244)
            ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pBA));
            break;
        }

        case WM_NCDESTROY: {
            LRESULT lres = ThemeDefWindowProc(pBA ? pBA->_theme : nullptr, hWnd, uMsg, wParam, lParam);
            ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0);
            return lres;
        }

        case WM_CREATE: 
            if (!pBA->OnCreate(hWnd)) {
                return -1;
            }
            break;

        case WM_QUERYENDSESSION:
            return IDCANCEL != pBA->OnSystemShutdown(static_cast<DWORD>(lParam), IDCANCEL);

        case WM_CLOSE:
            // If the user chose not to close, do *not* let the default window proc handle the message.
            if (!pBA->OnClose()) {
                return 0;
            }
            break;

        case WM_DESTROY:
            ::PostQuitMessage(0);
            break;

        case WM_PAINT: __fallthrough;
        case WM_ERASEBKGND:
            if (pBA && pBA->_suppressPaint) {
                return TRUE;
            }
            break;

        case WM_PYBA_SHOW_HELP:
            pBA->OnShowHelp();
            return 0;

        case WM_PYBA_DETECT_PACKAGES:
            pBA->OnDetect();
            return 0;

        case WM_PYBA_PLAN_PACKAGES:
            pBA->OnPlan(static_cast<BOOTSTRAPPER_ACTION>(lParam));
            return 0;

        case WM_PYBA_APPLY_PACKAGES:
            pBA->OnApply();
            return 0;

        case WM_PYBA_CHANGE_STATE:
            pBA->OnChangeState(static_cast<PYBA_STATE>(lParam));
            return 0;

        case WM_PYBA_SHOW_FAILURE:
            pBA->OnShowFailure();
            return 0;

        case WM_COMMAND:
            switch (LOWORD(wParam)) {
            // Customize commands
            // Success/failure commands
            case ID_SUCCESS_RESTART_BUTTON: __fallthrough;
            case ID_FAILURE_RESTART_BUTTON:
                pBA->OnClickRestartButton();
                return 0;

            case IDCANCEL: __fallthrough;
            case ID_INSTALL_CANCEL_BUTTON: __fallthrough;
            case ID_CUSTOM1_CANCEL_BUTTON: __fallthrough;
            case ID_CUSTOM2_CANCEL_BUTTON: __fallthrough;
            case ID_MODIFY_CANCEL_BUTTON: __fallthrough;
            case ID_PROGRESS_CANCEL_BUTTON: __fallthrough;
            case ID_SUCCESS_CANCEL_BUTTON: __fallthrough;
            case ID_FAILURE_CANCEL_BUTTON: __fallthrough;
            case ID_CLOSE_BUTTON:
                pBA->OnCommand(ID_CLOSE_BUTTON);
                return 0;

            default:
                pBA->OnCommand((CONTROL_ID)LOWORD(wParam));
            }
            break;

        case WM_NOTIFY:
            if (lParam) {
                LPNMHDR pnmhdr = reinterpret_cast<LPNMHDR>(lParam);
                switch (pnmhdr->code) {
                case NM_CLICK: __fallthrough;
                case NM_RETURN:
                    switch (static_cast<DWORD>(pnmhdr->idFrom)) {
                    case ID_FAILURE_LOGFILE_LINK:
                        pBA->OnClickLogFileLink();
                        return 1;
                    }
                }
            }
            break;

        case WM_CTLCOLORSTATIC:
        case WM_CTLCOLORBTN:
            if (pBA) {
                HBRUSH brush = nullptr;
                if (pBA->SetControlColor((HWND)lParam, (HDC)wParam, &brush)) {
                    return (LRESULT)brush;
                }
            }
            break;
        }

        if (pBA && pBA->_taskbarList && uMsg == pBA->_taskbarButtonCreatedMessage) {
            pBA->_taskbarButtonOK = TRUE;
            return 0;
        }

        return ThemeDefWindowProc(pBA ? pBA->_theme : nullptr, hWnd, uMsg, wParam, lParam);
    }

    //
    // OnCreate - finishes loading the theme.
    //
    BOOL OnCreate(__in HWND hWnd) {
        HRESULT hr = S_OK;

        hr = ThemeLoadControls(_theme, hWnd, CONTROL_ID_NAMES, countof(CONTROL_ID_NAMES));
        BalExitOnFailure(hr, "Failed to load theme controls.");

        C_ASSERT(COUNT_PAGE == countof(PAGE_NAMES));
        C_ASSERT(countof(_pageIds) == countof(PAGE_NAMES));

        ThemeGetPageIds(_theme, PAGE_NAMES, _pageIds, countof(_pageIds));

        // Initialize the text on all "application" (non-page) controls.
        for (DWORD i = 0; i < _theme->cControls; ++i) {
            THEME_CONTROL* pControl = _theme->rgControls + i;
            LPWSTR text = nullptr;

            if (!pControl->wPageId && pControl->sczText && *pControl->sczText) {
                HRESULT hrFormat;
                
                // If the wix developer is showing a hidden variable in the UI,
                // then obviously they don't care about keeping it safe so don't
                // go down the rabbit hole of making sure that this is securely
                // freed.
                hrFormat = BalFormatString(pControl->sczText, &text);
                if (SUCCEEDED(hrFormat)) {
                    ThemeSetTextControl(_theme, pControl->wId, text);
                    ReleaseStr(text);
                }
            }
        }

    LExit:
        return SUCCEEDED(hr);
    }

    void RemapColor(COLORREF *fg, COLORREF *bg, HBRUSH *bgBrush) {
        if (*fg == RGB(0, 0, 0)) {
            *fg = GetSysColor(COLOR_WINDOWTEXT);
        } else if (*fg == RGB(128, 128, 128)) {
            *fg = GetSysColor(COLOR_GRAYTEXT);
        }
        if (*bgBrush && *bg == RGB(255, 255, 255)) {
            *bg = GetSysColor(COLOR_WINDOW);
            *bgBrush = GetSysColorBrush(COLOR_WINDOW);
        }
    }

    BOOL SetControlColor(HWND hWnd, HDC hDC, HBRUSH *brush) {
        for (int i = 0; i < _theme->cControls; ++i) {
            if (_theme->rgControls[i].hWnd != hWnd) {
                continue;
            }

            DWORD fontId = _theme->rgControls[i].dwFontId;
            if (fontId > _theme->cFonts) {
                fontId = 0;
            }
            THEME_FONT *fnt = &_theme->rgFonts[fontId];

            COLORREF fg = fnt->crForeground, bg = fnt->crBackground;
            *brush = fnt->hBackground;
            RemapColor(&fg, &bg, brush);
            ::SetTextColor(hDC, fg);
            ::SetBkColor(hDC, bg);

            return TRUE;
        }
        return FALSE;
    }

    //
    // OnShowFailure - display the failure page.
    //
    void OnShowFailure() {
        SetState(PYBA_STATE_FAILED, S_OK);

        // If the UI should be visible, display it now and hide the splash screen
        if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) {
            ::ShowWindow(_theme->hwndParent, SW_SHOW);
        }

        _engine->CloseSplashScreen();

        return;
    }


    //
    // OnShowHelp - display the help page.
    //
    void OnShowHelp() {
        SetState(PYBA_STATE_HELP, S_OK);

        // If the UI should be visible, display it now and hide the splash screen
        if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) {
            ::ShowWindow(_theme->hwndParent, SW_SHOW);
        }

        _engine->CloseSplashScreen();

        return;
    }


    //
    // OnDetect - start the processing of packages.
    //
    void OnDetect() {
        HRESULT hr = S_OK;

        if (_baFunction) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect BA function");
            hr = _baFunction->OnDetect();
            BalExitOnFailure(hr, "Failed calling detect BA function.");
        }

        SetState(PYBA_STATE_DETECTING, hr);

        // If the UI should be visible, display it now and hide the splash screen
        if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) {
            ::ShowWindow(_theme->hwndParent, SW_SHOW);
        }

        _engine->CloseSplashScreen();

        // Tell the core we're ready for the packages to be processed now.
        hr = _engine->Detect();
        BalExitOnFailure(hr, "Failed to start detecting chain.");

    LExit:
        if (FAILED(hr)) {
            SetState(PYBA_STATE_DETECTING, hr);
        }

        return;
    }

    HRESULT UpdateUIStrings(__in BOOTSTRAPPER_ACTION action) {
        HRESULT hr = S_OK;
        LPCWSTR likeInstalling = nullptr;
        LPCWSTR likeInstallation = nullptr;
        switch (action) {
        case BOOTSTRAPPER_ACTION_INSTALL:
            likeInstalling = L"Installing";
            likeInstallation = L"Installation";
            break;
        case BOOTSTRAPPER_ACTION_MODIFY:
            // For modify, we actually want to pass INSTALL
            action = BOOTSTRAPPER_ACTION_INSTALL;
            likeInstalling = L"Modifying";
            likeInstallation = L"Modification";
            break;
        case BOOTSTRAPPER_ACTION_REPAIR:
            likeInstalling = L"Repairing";
            likeInstallation = L"Repair";
            break;
        case BOOTSTRAPPER_ACTION_UNINSTALL:
            likeInstalling = L"Uninstalling";
            likeInstallation = L"Uninstallation";
            break;
        }

        if (likeInstalling) {
            LPWSTR locName = nullptr;
            LOC_STRING *locText = nullptr;
            hr = StrAllocFormatted(&locName, L"#(loc.%ls)", likeInstalling);
            if (SUCCEEDED(hr)) {
                hr = LocGetString(_wixLoc, locName, &locText);
                ReleaseStr(locName);
            }
            _engine->SetVariableString(
                L"ActionLikeInstalling",
                SUCCEEDED(hr) && locText ? locText->wzText : likeInstalling
            );
        }

        if (likeInstallation) {
            LPWSTR locName = nullptr;
            LOC_STRING *locText = nullptr;
            hr = StrAllocFormatted(&locName, L"#(loc.%ls)", likeInstallation);
            if (SUCCEEDED(hr)) {
                hr = LocGetString(_wixLoc, locName, &locText);
                ReleaseStr(locName);
            }
            _engine->SetVariableString(
                L"ActionLikeInstallation",
                SUCCEEDED(hr) && locText ? locText->wzText : likeInstallation
            );
        }
        return hr;
    }

    //
    // OnPlan - plan the detected changes.
    //
    void OnPlan(__in BOOTSTRAPPER_ACTION action) {
        HRESULT hr = S_OK;

        _plannedAction = action;

        hr = UpdateUIStrings(action);
        BalExitOnFailure(hr, "Failed to update strings");

        // If we are going to apply a downgrade, bail.
        if (_downgradingOtherVersion && BOOTSTRAPPER_ACTION_UNINSTALL < action) {
            if (_suppressDowngradeFailure) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "A newer version of this product is installed but downgrade failure has been suppressed; continuing...");
            } else {
                hr = HRESULT_FROM_WIN32(ERROR_PRODUCT_VERSION);
                BalExitOnFailure(hr, "Cannot install a product when a newer version is installed.");
            }
        }

        SetState(PYBA_STATE_PLANNING, hr);

        if (_baFunction) {
            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running plan BA function");
            _baFunction->OnPlan();
        }

        hr = _engine->Plan(action);
        BalExitOnFailure(hr, "Failed to start planning packages.");

    LExit:
        if (FAILED(hr)) {
            SetState(PYBA_STATE_PLANNING, hr);
        }

        return;
    }


    //
    // OnApply - apply the packages.
    //
    void OnApply() {
        HRESULT hr = S_OK;

        SetState(PYBA_STATE_APPLYING, hr);
        SetProgressState(hr);
        SetTaskbarButtonProgress(0);

        hr = _engine->Apply(_hWnd);
        BalExitOnFailure(hr, "Failed to start applying packages.");

        ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, TRUE); // ensure the cancel button is enabled before starting.

    LExit:
        if (FAILED(hr)) {
            SetState(PYBA_STATE_APPLYING, hr);
        }

        return;
    }


    //
    // OnChangeState - change state.
    //
    void OnChangeState(__in PYBA_STATE state) {
        LPWSTR unformattedText = nullptr;

        _state = state;

        // If our install is at the end (success or failure) and we're not showing full UI
        // then exit (prompt for restart if required).
        if ((PYBA_STATE_APPLIED <= _state && BOOTSTRAPPER_DISPLAY_FULL > _command.display)) {
            // If a restart was required but we were not automatically allowed to
            // accept the reboot then do the prompt.
            if (_restartRequired && !_allowRestart) {
                StrAllocFromError(&unformattedText, HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), nullptr);

                _allowRestart = IDOK == ::MessageBoxW(
                    _hWnd,
                    unformattedText ? unformattedText : L"The requested operation is successful. Changes will not be effective until the system is rebooted.",
                    _theme->sczCaption,
                    MB_ICONEXCLAMATION | MB_OKCANCEL
                );
            }

            // Quietly exit.
            ::PostMessageW(_hWnd, WM_CLOSE, 0, 0);
        } else { // try to change the pages.
            DWORD newPageId = 0;
            DeterminePageId(_state, &newPageId);

            if (_visiblePageId != newPageId) {
                ShowPage(newPageId);
            }
        }

        ReleaseStr(unformattedText);
    }

    //
    // Called before showing a page to handle all controls.
    //
    void ProcessPageControls(THEME_PAGE *pPage) {
        if (!pPage) {
            return;
        }

        for (DWORD i = 0; i < pPage->cControlIndices; ++i) {
            THEME_CONTROL* pControl = _theme->rgControls + pPage->rgdwControlIndices[i];
            BOOL enableControl = TRUE;

            // If this is a named control, try to set its default state.
            if (pControl->sczName && *pControl->sczName) {
                // If this is a checkable control, try to set its default state
                // to the state of a matching named Burn variable.
                if (IsCheckable(pControl)) {
                    LONGLONG llValue = 0;
                    HRESULT hr = BalGetNumericVariable(pControl->sczName, &llValue);

                    // If the control value isn't set then disable it.
                    if (!SUCCEEDED(hr)) {
                        enableControl = FALSE;
                    } else {
                        ThemeSendControlMessage(
                            _theme,
                            pControl->wId,
                            BM_SETCHECK,
                            SUCCEEDED(hr) && llValue ? BST_CHECKED : BST_UNCHECKED,
                            0
                        );
                    }
                }

                // Hide or disable controls based on the control name with 'State' appended
                LPWSTR controlName = nullptr;
                HRESULT hr = StrAllocFormatted(&controlName, L"%lsState", pControl->sczName);
                if (SUCCEEDED(hr)) {
                    LPWSTR controlState = nullptr;
                    hr = BalGetStringVariable(controlName, &controlState);
                    if (SUCCEEDED(hr) && controlState && *controlState) {
                        if (controlState[0] == '[') {
                            LPWSTR formatted = nullptr;
                            if (SUCCEEDED(BalFormatString(controlState, &formatted))) {
                                StrFree(controlState);
                                controlState = formatted;
                            }
                        }

                        if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, controlState, -1, L"disable", -1)) {
                            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Disable control %ls", pControl->sczName);
                            enableControl = FALSE;
                        } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, controlState, -1, L"hide", -1)) {
                            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Hide control %ls", pControl->sczName);
                            // TODO: This doesn't work
                            ThemeShowControl(_theme, pControl->wId, SW_HIDE);
                        } else {
                            // An explicit state can override the lack of a
                            // backing variable.
                            enableControl = TRUE;
                        }
                    }
                    StrFree(controlState);
                }
                StrFree(controlName);
                controlName = nullptr;


                // If a command link has a note, then add it.
                if ((pControl->dwStyle & BS_TYPEMASK) == BS_COMMANDLINK ||
                    (pControl->dwStyle & BS_TYPEMASK) == BS_DEFCOMMANDLINK) {
                    hr = StrAllocFormatted(&controlName, L"#(loc.%lsNote)", pControl->sczName);
                    if (SUCCEEDED(hr)) {
                        LOC_STRING *locText = nullptr;
                        hr = LocGetString(_wixLoc, controlName, &locText);
                        if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) {
                            LPWSTR text = nullptr;
                            hr = BalFormatString(locText->wzText, &text);
                            if (SUCCEEDED(hr) && text && text[0]) {
                                ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text);
                                ReleaseStr(text);
                                text = nullptr;
                            }
                        }
                        ReleaseStr(controlName);
                        controlName = nullptr;
                    }
                    hr = S_OK;
                }
            }

            ThemeControlEnable(_theme, pControl->wId, enableControl);

            // Format the text in each of the new page's controls
            if (pControl->sczText && *pControl->sczText) {
                // If the wix developer is showing a hidden variable
                // in the UI, then obviously they don't care about
                // keeping it safe so don't go down the rabbit hole
                // of making sure that this is securely freed.
                LPWSTR text = nullptr;
                HRESULT hr = BalFormatString(pControl->sczText, &text);
                if (SUCCEEDED(hr)) {
                    ThemeSetTextControl(_theme, pControl->wId, text);
                }
            }
        }
    }

    //
    // OnClose - called when the window is trying to be closed.
    //
    BOOL OnClose() {
        BOOL close = FALSE;

        // If we've already succeeded or failed or showing the help page, just close (prompts are annoying if the bootstrapper is done).
        if (PYBA_STATE_APPLIED <= _state || PYBA_STATE_HELP == _state) {
            close = TRUE;
        } else {
            // prompt the user or force the cancel if there is no UI.
            close = PromptCancel(
                _hWnd,
                BOOTSTRAPPER_DISPLAY_FULL != _command.display,
                _confirmCloseMessage ? _confirmCloseMessage : L"Are you sure you want to cancel?",
                _theme->sczCaption
            );
        }

        // If we're doing progress then we never close, we just cancel to let rollback occur.
        if (PYBA_STATE_APPLYING <= _state && PYBA_STATE_APPLIED > _state) {
            // If we canceled disable cancel button since clicking it again is silly.
            if (close) {
                ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, FALSE);
            }

            close = FALSE;
        }

        return close;
    }

    //
    // OnClickCloseButton - close the application.
    //
    void OnClickCloseButton() {
        ::SendMessageW(_hWnd, WM_CLOSE, 0, 0);
    }



    //
    // OnClickRestartButton - allows the restart and closes the app.
    //
    void OnClickRestartButton() {
        AssertSz(_restartRequired, "Restart must be requested to be able to click on the restart button.");

        _allowRestart = TRUE;
        ::SendMessageW(_hWnd, WM_CLOSE, 0, 0);

        return;
    }


    //
    // OnClickLogFileLink - show the log file.
    //
    void OnClickLogFileLink() {
        HRESULT hr = S_OK;
        LPWSTR sczLogFile = nullptr;

        hr = BalGetStringVariable(_bundle.sczLogVariable, &sczLogFile);
        BalExitOnFailure1(hr, "Failed to get log file variable '%ls'.", _bundle.sczLogVariable);

        hr = ShelExec(L"notepad.exe", sczLogFile, L"open", nullptr, SW_SHOWDEFAULT, _hWnd, nullptr);
        BalExitOnFailure1(hr, "Failed to open log file target: %ls", sczLogFile);

    LExit:
        ReleaseStr(sczLogFile);

        return;
    }


    //
    // SetState
    //
    void SetState(__in PYBA_STATE state, __in HRESULT hrStatus) {
        if (FAILED(hrStatus)) {
            _hrFinal = hrStatus;
        }

        if (FAILED(_hrFinal)) {
            state = PYBA_STATE_FAILED;
        }

        if (_state != state) {
            ::PostMessageW(_hWnd, WM_PYBA_CHANGE_STATE, 0, state);
        }
    }

    //
    // GoToPage
    //
    void GoToPage(__in PAGE page) {
        _installPage = page;
        ::PostMessageW(_hWnd, WM_PYBA_CHANGE_STATE, 0, _state);
    }

    void DeterminePageId(__in PYBA_STATE state, __out DWORD* pdwPageId) {
        LONGLONG simple;

        if (BOOTSTRAPPER_DISPLAY_PASSIVE == _command.display) {
            switch (state) {
            case PYBA_STATE_INITIALIZED:
                *pdwPageId = BOOTSTRAPPER_ACTION_HELP == _command.action
                    ? _pageIds[PAGE_HELP]
                    : _pageIds[PAGE_LOADING];
                break;

            case PYBA_STATE_HELP:
                *pdwPageId = _pageIds[PAGE_HELP];
                break;

            case PYBA_STATE_DETECTING:
                *pdwPageId = _pageIds[PAGE_LOADING]
                    ? _pageIds[PAGE_LOADING]
                    : _pageIds[PAGE_PROGRESS_PASSIVE]
                        ? _pageIds[PAGE_PROGRESS_PASSIVE]
                        : _pageIds[PAGE_PROGRESS];
                break;

            case PYBA_STATE_DETECTED: __fallthrough;
            case PYBA_STATE_PLANNING: __fallthrough;
            case PYBA_STATE_PLANNED: __fallthrough;
            case PYBA_STATE_APPLYING: __fallthrough;
            case PYBA_STATE_CACHING: __fallthrough;
            case PYBA_STATE_CACHED: __fallthrough;
            case PYBA_STATE_EXECUTING: __fallthrough;
            case PYBA_STATE_EXECUTED:
                *pdwPageId = _pageIds[PAGE_PROGRESS_PASSIVE]
                    ? _pageIds[PAGE_PROGRESS_PASSIVE]
                    : _pageIds[PAGE_PROGRESS];
                break;

            default:
                *pdwPageId = 0;
                break;
            }
        } else if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) {
            switch (state) {
            case PYBA_STATE_INITIALIZING:
                *pdwPageId = 0;
                break;

            case PYBA_STATE_INITIALIZED:
                *pdwPageId = BOOTSTRAPPER_ACTION_HELP == _command.action
                    ? _pageIds[PAGE_HELP]
                    : _pageIds[PAGE_LOADING];
                break;

            case PYBA_STATE_HELP:
                *pdwPageId = _pageIds[PAGE_HELP];
                break;

            case PYBA_STATE_DETECTING:
                *pdwPageId = _pageIds[PAGE_LOADING];
                break;

            case PYBA_STATE_DETECTED:
                if (_installPage == PAGE_LOADING) {
                    switch (_command.action) {
                    case BOOTSTRAPPER_ACTION_INSTALL:
                        if (_upgrading) {
                            _installPage = PAGE_UPGRADE;
                        } else if (SUCCEEDED(BalGetNumericVariable(L"SimpleInstall", &simple)) && simple) {
                            _installPage = PAGE_SIMPLE_INSTALL;
                        } else {
                            _installPage = PAGE_INSTALL;
                        }
                        break;

                    case BOOTSTRAPPER_ACTION_MODIFY: __fallthrough;
                    case BOOTSTRAPPER_ACTION_REPAIR: __fallthrough;
                    case BOOTSTRAPPER_ACTION_UNINSTALL:
                        _installPage = PAGE_MODIFY;
                        break;
                    }
                }
                *pdwPageId = _pageIds[_installPage];
                break;

            case PYBA_STATE_PLANNING: __fallthrough;
            case PYBA_STATE_PLANNED: __fallthrough;
            case PYBA_STATE_APPLYING: __fallthrough;
            case PYBA_STATE_CACHING: __fallthrough;
            case PYBA_STATE_CACHED: __fallthrough;
            case PYBA_STATE_EXECUTING: __fallthrough;
            case PYBA_STATE_EXECUTED:
                *pdwPageId = _pageIds[PAGE_PROGRESS];
                break;

            case PYBA_STATE_APPLIED:
                *pdwPageId = _pageIds[PAGE_SUCCESS];
                break;

            case PYBA_STATE_FAILED:
                *pdwPageId = _pageIds[PAGE_FAILURE];
                break;
            }
        }
    }

    BOOL WillElevate() {
        static BAL_CONDITION WILL_ELEVATE_CONDITION = {
            L"not WixBundleElevated and ("
                /*Elevate when installing for all users*/
                L"InstallAllUsers or "
                /*Elevate when installing the launcher for all users and it was not detected*/
                L"(Include_launcher and InstallLauncherAllUsers and not DetectedLauncher)"
            L")",
            L""
        };
        BOOL result;

        return SUCCEEDED(BalConditionEvaluate(&WILL_ELEVATE_CONDITION, _engine, &result, nullptr)) && result;
    }

    BOOL IsCrtInstalled() {
        if (_crtInstalledToken > 0) {
            return TRUE;
        } else if (_crtInstalledToken == 0) {
            return FALSE;
        }
        
        // Check whether at least CRT v10.0.10137.0 is available.
        // It should only be installed as a Windows Update package, which means
        // we don't need to worry about 32-bit/64-bit.
        LPCWSTR crtFile = L"ucrtbase.dll";

        DWORD cbVer = GetFileVersionInfoSizeW(crtFile, nullptr);
        if (!cbVer) {
            _crtInstalledToken = 0;
            return FALSE;
        }

        void *pData = malloc(cbVer);
        if (!pData) {
            _crtInstalledToken = 0;
            return FALSE;
        }

        if (!GetFileVersionInfoW(crtFile, 0, cbVer, pData)) {
            free(pData);
            _crtInstalledToken = 0;
            return FALSE;
        }

        VS_FIXEDFILEINFO *ffi;
        UINT cb;
        BOOL result = FALSE;

        if (VerQueryValueW(pData, L"\\", (LPVOID*)&ffi, &cb) &&
            ffi->dwFileVersionMS == 0x000A0000 && ffi->dwFileVersionLS >= 0x27990000) {
            result = TRUE;
        }
        
        free(pData);
        _crtInstalledToken = result ? 1 : 0;
        return result;
    }

    HRESULT EvaluateConditions() {
        HRESULT hr = S_OK;
        BOOL result = FALSE;

        for (DWORD i = 0; i < _conditions.cConditions; ++i) {
            BAL_CONDITION* pCondition = _conditions.rgConditions + i;

            hr = BalConditionEvaluate(pCondition, _engine, &result, &_failedMessage);
            BalExitOnFailure(hr, "Failed to evaluate condition.");

            if (!result) {
                // Hope they didn't have hidden variables in their message, because it's going in the log in plaintext.
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "%ls", _failedMessage);

                hr = E_WIXSTDBA_CONDITION_FAILED;
                // todo: remove in WiX v4, in case people are relying on v3.x logging behavior
                BalExitOnFailure1(hr, "Bundle condition evaluated to false: %ls", pCondition->sczCondition);
            }
        }

        ReleaseNullStrSecure(_failedMessage);

    LExit:
        return hr;
    }


    void SetTaskbarButtonProgress(__in DWORD dwOverallPercentage) {
        HRESULT hr = S_OK;

        if (_taskbarButtonOK) {
            hr = _taskbarList->SetProgressValue(_hWnd, dwOverallPercentage, 100UL);
            BalExitOnFailure1(hr, "Failed to set taskbar button progress to: %d%%.", dwOverallPercentage);
        }

    LExit:
        return;
    }


    void SetTaskbarButtonState(__in TBPFLAG tbpFlags) {
        HRESULT hr = S_OK;

        if (_taskbarButtonOK) {
            hr = _taskbarList->SetProgressState(_hWnd, tbpFlags);
            BalExitOnFailure1(hr, "Failed to set taskbar button state.", tbpFlags);
        }

    LExit:
        return;
    }


    void SetProgressState(__in HRESULT hrStatus) {
        TBPFLAG flag = TBPF_NORMAL;

        if (IsCanceled() || HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hrStatus) {
            flag = TBPF_PAUSED;
        } else if (IsRollingBack() || FAILED(hrStatus)) {
            flag = TBPF_ERROR;
        }

        SetTaskbarButtonState(flag);
    }


    HRESULT LoadBootstrapperBAFunctions() {
        HRESULT hr = S_OK;
        LPWSTR sczBafPath = nullptr;

        hr = PathRelativeToModule(&sczBafPath, L"bafunctions.dll", _hModule);
        BalExitOnFailure(hr, "Failed to get path to BA function DLL.");

#ifdef DEBUG
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: LoadBootstrapperBAFunctions() - BA function DLL %ls", sczBafPath);
#endif

        _hBAFModule = ::LoadLibraryW(sczBafPath);
        if (_hBAFModule) {
            auto pfnBAFunctionCreate = reinterpret_cast<PFN_BOOTSTRAPPER_BA_FUNCTION_CREATE>(::GetProcAddress(_hBAFModule, "CreateBootstrapperBAFunction"));
            BalExitOnNullWithLastError1(pfnBAFunctionCreate, hr, "Failed to get CreateBootstrapperBAFunction entry-point from: %ls", sczBafPath);

            hr = pfnBAFunctionCreate(_engine, _hBAFModule, &_baFunction);
            BalExitOnFailure(hr, "Failed to create BA function.");
        }
#ifdef DEBUG
        else {
            BalLogError(HRESULT_FROM_WIN32(::GetLastError()), "PYBA: LoadBootstrapperBAFunctions() - Failed to load DLL %ls", sczBafPath);
        }
#endif

    LExit:
        if (_hBAFModule && !_baFunction) {
            ::FreeLibrary(_hBAFModule);
            _hBAFModule = nullptr;
        }
        ReleaseStr(sczBafPath);

        return hr;
    }

    BOOL IsCheckable(THEME_CONTROL* pControl) {
        if (!pControl->sczName || !pControl->sczName[0]) {
            return FALSE;
        }

        if (pControl->type == THEME_CONTROL_TYPE_CHECKBOX) {
            return TRUE;
        }

        if (pControl->type == THEME_CONTROL_TYPE_BUTTON) {
            if ((pControl->dwStyle & BS_TYPEMASK) == BS_AUTORADIOBUTTON) {
                return TRUE;
            }
        }

        return FALSE;
    }

    void SavePageSettings() {
        DWORD pageId = 0;
        THEME_PAGE* pPage = nullptr;

        DeterminePageId(_state, &pageId);
        pPage = ThemeGetPage(_theme, pageId);
        if (!pPage) {
            return;
        }

        for (DWORD i = 0; i < pPage->cControlIndices; ++i) {
            // Loop through all the checkable controls and set a Burn variable
            // with that name to true or false.
            THEME_CONTROL* pControl = _theme->rgControls + pPage->rgdwControlIndices[i];
            if (IsCheckable(pControl) && ThemeControlEnabled(_theme, pControl->wId)) {
                BOOL checked = ThemeIsControlChecked(_theme, pControl->wId);
                _engine->SetVariableNumeric(pControl->sczName, checked ? 1 : 0);
            }

            // Loop through all the editbox controls with names and set a
            // Burn variable with that name to the contents.
            if (THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName) {
                LPWSTR sczValue = nullptr;
                ThemeGetTextControl(_theme, pControl->wId, &sczValue);
                _engine->SetVariableString(pControl->sczName, sczValue);
            }
        }
    }

    static bool IsTargetPlatformx64(__in IBootstrapperEngine* pEngine) {
        WCHAR platform[8];
        DWORD platformLen = 8;

        if (FAILED(pEngine->GetVariableString(L"TargetPlatform", platform, &platformLen))) {
            return S_FALSE;
        }

        return ::CompareStringW(LOCALE_NEUTRAL, 0, platform, -1, L"x64", -1) == CSTR_EQUAL;
    }

    static bool IsTargetPlatformARM64(__in IBootstrapperEngine* pEngine) {
        WCHAR platform[8];
        DWORD platformLen = 8;

        if (FAILED(pEngine->GetVariableString(L"TargetPlatform", platform, &platformLen))) {
            return S_FALSE;
        }

        return ::CompareStringW(LOCALE_NEUTRAL, 0, platform, -1, L"ARM64", -1) == CSTR_EQUAL;
    }

    static HRESULT LoadOptionalFeatureStatesFromKey(
        __in IBootstrapperEngine* pEngine,
        __in HKEY hkHive,
        __in LPCWSTR subkey
    ) {
        HKEY hKey;
        LRESULT res;

        if (IsTargetPlatformx64(pEngine) || IsTargetPlatformARM64(pEngine)) {
            res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
        } else {
            res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
        }
        if (res == ERROR_FILE_NOT_FOUND) {
            return S_FALSE;
        }
        if (res != ERROR_SUCCESS) {
            return HRESULT_FROM_WIN32(res);
        }

        for (auto p = OPTIONAL_FEATURES; p->regName; ++p) {
            res = RegQueryValueExW(hKey, p->regName, nullptr, nullptr, nullptr, nullptr);
            if (res == ERROR_FILE_NOT_FOUND) {
                pEngine->SetVariableNumeric(p->variableName, 0);
            } else if (res == ERROR_SUCCESS) {
                pEngine->SetVariableNumeric(p->variableName, 1);
            } else {
                RegCloseKey(hKey);
                return HRESULT_FROM_WIN32(res);
            }
        }

        RegCloseKey(hKey);
        return S_OK;
    }

    static HRESULT LoadTargetDirFromKey(
        __in IBootstrapperEngine* pEngine,
        __in HKEY hkHive,
        __in LPCWSTR subkey
    ) {
        HKEY hKey;
        LRESULT res;
        DWORD dataType;
        BYTE buffer[1024];
        DWORD bufferLen = sizeof(buffer);

        if (IsTargetPlatformx64(pEngine) || IsTargetPlatformARM64(pEngine)) {
            res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
        } else {
            res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
        }
        if (res == ERROR_FILE_NOT_FOUND) {
            return S_FALSE;
        }
        if (res != ERROR_SUCCESS) {
            return HRESULT_FROM_WIN32(res);
        }

        res = RegQueryValueExW(hKey, nullptr, nullptr, &dataType, buffer, &bufferLen);
        if (res == ERROR_SUCCESS && dataType == REG_SZ && bufferLen < sizeof(buffer)) {
            pEngine->SetVariableString(L"TargetDir", reinterpret_cast<wchar_t*>(buffer));
        }
        RegCloseKey(hKey);
        return HRESULT_FROM_WIN32(res);
    }

    static HRESULT LoadAssociateFilesStateFromKey(
        __in IBootstrapperEngine* pEngine,
        __in HKEY hkHive
    ) {
        const LPCWSTR subkey = L"Software\\Python\\PyLauncher";
        HKEY hKey;
        LRESULT res;
        HRESULT hr;

        res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);

        if (res == ERROR_FILE_NOT_FOUND) {
            return S_FALSE;
        }
        if (res != ERROR_SUCCESS) {
            return HRESULT_FROM_WIN32(res);
        }

        res = RegQueryValueExW(hKey, L"AssociateFiles", nullptr, nullptr, nullptr, nullptr);
        if (res == ERROR_FILE_NOT_FOUND) {
            hr = S_FALSE;
        } else if (res == ERROR_SUCCESS) {
            hr = S_OK;
        } else {
            hr = HRESULT_FROM_WIN32(res);
        }

        RegCloseKey(hKey);
        return hr;
    }

    static void LoadOptionalFeatureStates(__in IBootstrapperEngine* pEngine) {
        WCHAR subkeyFmt[256];
        WCHAR subkey[256];
        DWORD subkeyLen;
        HRESULT hr;
        HKEY hkHive;

        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading state of optional features");

        // Get the registry key from the bundle, to save having to duplicate it
        // in multiple places.
        subkeyLen = sizeof(subkeyFmt) / sizeof(subkeyFmt[0]);
        hr = pEngine->GetVariableString(L"OptionalFeaturesRegistryKey", subkeyFmt, &subkeyLen);
        BalExitOnFailure(hr, "Failed to locate registry key");
        subkeyLen = sizeof(subkey) / sizeof(subkey[0]);
        hr = pEngine->FormatString(subkeyFmt, subkey, &subkeyLen);
        BalExitOnFailure1(hr, "Failed to format %ls", subkeyFmt);

        // Check the current user's registry for existing features
        hkHive = HKEY_CURRENT_USER;
        hr = LoadOptionalFeatureStatesFromKey(pEngine, hkHive, subkey);
        BalExitOnFailure1(hr, "Failed to read from HKCU\\%ls", subkey);
        if (hr == S_FALSE) {
            // Now check the local machine registry
            hkHive = HKEY_LOCAL_MACHINE;
            hr = LoadOptionalFeatureStatesFromKey(pEngine, hkHive, subkey);
            BalExitOnFailure1(hr, "Failed to read from HKLM\\%ls", subkey);
            if (hr == S_OK) {
                // Found a system-wide install, so enable these settings.
                pEngine->SetVariableNumeric(L"InstallAllUsers", 1);
                pEngine->SetVariableNumeric(L"CompileAll", 1);
            }
        }

        if (hr == S_OK) {
            // Cannot change InstallAllUsersState when upgrading. While there's
            // no good reason to not allow installing a per-user and an all-user
            // version simultaneously, Burn can't handle the state management
            // and will need to uninstall the old one. 
            pEngine->SetVariableString(L"InstallAllUsersState", L"disable");

            // Get the previous install directory. This can be changed by the
            // user.
            subkeyLen = sizeof(subkeyFmt) / sizeof(subkeyFmt[0]);
            hr = pEngine->GetVariableString(L"TargetDirRegistryKey", subkeyFmt, &subkeyLen);
            BalExitOnFailure(hr, "Failed to locate registry key");
            subkeyLen = sizeof(subkey) / sizeof(subkey[0]);
            hr = pEngine->FormatString(subkeyFmt, subkey, &subkeyLen);
            BalExitOnFailure1(hr, "Failed to format %ls", subkeyFmt);
            LoadTargetDirFromKey(pEngine, hkHive, subkey);
        }

    LExit:
        return;
    }

    HRESULT EnsureTargetDir() {
        LONGLONG installAllUsers;
        LPWSTR targetDir = nullptr, defaultDir = nullptr;
        HRESULT hr = BalGetStringVariable(L"TargetDir", &targetDir);
        if (FAILED(hr) || !targetDir || !targetDir[0]) {
            ReleaseStr(targetDir);
            targetDir = nullptr;

            hr = BalGetNumericVariable(L"InstallAllUsers", &installAllUsers);
            ExitOnFailure(hr, L"Failed to get install scope");

            hr = BalGetStringVariable(
                installAllUsers ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir",
                &defaultDir
            );
            BalExitOnFailure(hr, "Failed to get the default install directory");

            if (!defaultDir || !defaultDir[0]) {
                BalLogError(E_INVALIDARG, "Default install directory is blank");
            }

            hr = BalFormatString(defaultDir, &targetDir);
            BalExitOnFailure1(hr, "Failed to format '%ls'", defaultDir);

            hr = _engine->SetVariableString(L"TargetDir", targetDir);
            BalExitOnFailure(hr, "Failed to set install target directory");
        }
    LExit:
        ReleaseStr(defaultDir);
        ReleaseStr(targetDir);
        return hr;
    }

    void ValidateOperatingSystem() {
        LOC_STRING *pLocString = nullptr;
        
        if (IsWindowsServer()) {
            if (IsWindowsVersionOrGreater(6, 2, 0)) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows Server 2012 or later");
                return;
            } else if (IsWindowsVersionOrGreater(6, 1, 1)) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Detected Windows Server 2008 R2");
            } else if (IsWindowsVersionOrGreater(6, 1, 0)) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Server 2008 R2");
            } else if (IsWindowsVersionOrGreater(6, 0, 0)) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Server 2008");
            } else {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Server 2003 or earlier");
            }
            BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Windows Server 2012 or later is required to continue installation");
        } else {
            if (IsWindows10OrGreater()) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows 10 or later");
                return;
            } else if (IsWindows8Point1OrGreater()) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows 8.1");
                return;
            } else if (IsWindows8OrGreater()) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows 8");
            } else if (IsWindows7OrGreater()) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows 7");
            } else if (IsWindowsVistaOrGreater()) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Vista");
            } else { 
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows XP or earlier");
            }
            BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Windows 8.1 or later is required to continue installation");
        }

        LocGetString(_wixLoc, L"#(loc.FailureOldOS)", &pLocString);
        if (pLocString && pLocString->wzText) {
            BalFormatString(pLocString->wzText, &_failedMessage);
        }
        
        _hrFinal = E_WIXSTDBA_CONDITION_FAILED;
    }

public:
    //
    // Constructor - initialize member variables.
    //
    PythonBootstrapperApplication(
        __in HMODULE hModule,
        __in BOOL fPrereq,
        __in HRESULT hrHostInitialization,
        __in IBootstrapperEngine* pEngine,
        __in const BOOTSTRAPPER_COMMAND* pCommand
    ) : CBalBaseBootstrapperApplication(pEngine, pCommand, 3, 3000) {
        _hModule = hModule;
        memcpy_s(&_command, sizeof(_command), pCommand, sizeof(BOOTSTRAPPER_COMMAND));

        LONGLONG llInstalled = 0;
        HRESULT hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled);
        if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != _command.resumeType && 0 < llInstalled && BOOTSTRAPPER_ACTION_INSTALL == _command.action) {
            _command.action = BOOTSTRAPPER_ACTION_MODIFY;
        } else if (0 == llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == _command.action || BOOTSTRAPPER_ACTION_REPAIR == _command.action)) {
            _command.action = BOOTSTRAPPER_ACTION_INSTALL;
        }

        _plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN;


        // When resuming from restart doing some install-like operation, try to find the package that forced the
        // restart. We'll use this information during planning.
        _nextPackageAfterRestart = nullptr;

        if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == _command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < _command.action) {
            // Ensure the forced restart package variable is null when it is an empty string.
            HRESULT hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &_nextPackageAfterRestart);
            if (FAILED(hr) || !_nextPackageAfterRestart || !*_nextPackageAfterRestart) {
                ReleaseNullStr(_nextPackageAfterRestart);
            }
        }

        _crtInstalledToken = -1;
        pEngine->SetVariableNumeric(L"CRTInstalled", IsCrtInstalled() ? 1 : 0);

        _wixLoc = nullptr;
        memset(&_bundle, 0, sizeof(_bundle));
        memset(&_conditions, 0, sizeof(_conditions));
        _confirmCloseMessage = nullptr;
        _failedMessage = nullptr;

        _language = nullptr;
        _theme = nullptr;
        memset(_pageIds, 0, sizeof(_pageIds));
        _hUiThread = nullptr;
        _registered = FALSE;
        _hWnd = nullptr;

        _state = PYBA_STATE_INITIALIZING;
        _visiblePageId = 0;
        _installPage = PAGE_LOADING;
        _hrFinal = hrHostInitialization;

        _downgradingOtherVersion = FALSE;
        _restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
        _restartRequired = FALSE;
        _allowRestart = FALSE;

        _suppressDowngradeFailure = FALSE;
        _suppressRepair = FALSE;
        _modifying = FALSE;
        _upgrading = FALSE;

        _overridableVariables = nullptr;
        _taskbarList = nullptr;
        _taskbarButtonCreatedMessage = UINT_MAX;
        _taskbarButtonOK = FALSE;
        _showingInternalUIThisPackage = FALSE;

        _suppressPaint = FALSE;

        pEngine->AddRef();
        _engine = pEngine;

        _hBAFModule = nullptr;
        _baFunction = nullptr;
    }


    //
    // Destructor - release member variables.
    //
    ~PythonBootstrapperApplication() {
        AssertSz(!::IsWindow(_hWnd), "Window should have been destroyed before destructor.");
        AssertSz(!_theme, "Theme should have been released before destructor.");

        ReleaseObject(_taskbarList);
        ReleaseDict(_overridableVariables);
        ReleaseStr(_failedMessage);
        ReleaseStr(_confirmCloseMessage);
        BalConditionsUninitialize(&_conditions);
        BalInfoUninitialize(&_bundle);
        LocFree(_wixLoc);

        ReleaseStr(_language);
        ReleaseStr(_nextPackageAfterRestart);
        ReleaseNullObject(_engine);

        if (_hBAFModule) {
            ::FreeLibrary(_hBAFModule);
            _hBAFModule = nullptr;
        }
    }

private:
    HMODULE _hModule;
    BOOTSTRAPPER_COMMAND _command;
    IBootstrapperEngine* _engine;
    BOOTSTRAPPER_ACTION _plannedAction;

    LPWSTR _nextPackageAfterRestart;

    WIX_LOCALIZATION* _wixLoc;
    BAL_INFO_BUNDLE _bundle;
    BAL_CONDITIONS _conditions;
    LPWSTR _failedMessage;
    LPWSTR _confirmCloseMessage;

    LPWSTR _language;
    THEME* _theme;
    DWORD _pageIds[countof(PAGE_NAMES)];
    HANDLE _hUiThread;
    BOOL _registered;
    HWND _hWnd;

    PYBA_STATE _state;
    HRESULT _hrFinal;
    DWORD _visiblePageId;
    PAGE _installPage;

    BOOL _startedExecution;
    DWORD _calculatedCacheProgress;
    DWORD _calculatedExecuteProgress;

    BOOL _downgradingOtherVersion;
    BOOTSTRAPPER_APPLY_RESTART _restartResult;
    BOOL _restartRequired;
    BOOL _allowRestart;

    BOOL _suppressDowngradeFailure;
    BOOL _suppressRepair;
    BOOL _modifying;
    BOOL _upgrading;

    int _crtInstalledToken;

    STRINGDICT_HANDLE _overridableVariables;

    ITaskbarList3* _taskbarList;
    UINT _taskbarButtonCreatedMessage;
    BOOL _taskbarButtonOK;
    BOOL _showingInternalUIThisPackage;

    BOOL _suppressPaint;

    HMODULE _hBAFModule;
    IBootstrapperBAFunction* _baFunction;
};

//
// CreateBootstrapperApplication - creates a new IBootstrapperApplication object.
//
HRESULT CreateBootstrapperApplication(
    __in HMODULE hModule,
    __in BOOL fPrereq,
    __in HRESULT hrHostInitialization,
    __in IBootstrapperEngine* pEngine,
    __in const BOOTSTRAPPER_COMMAND* pCommand,
    __out IBootstrapperApplication** ppApplication
    ) {
    HRESULT hr = S_OK;

    if (fPrereq) {
        hr = E_INVALIDARG;
        ExitWithLastError(hr, "Failed to create UI thread.");
    }

    PythonBootstrapperApplication* pApplication = nullptr;

    pApplication = new PythonBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine, pCommand);
    ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object.");

    *ppApplication = pApplication;
    pApplication = nullptr;

LExit:
    ReleaseObject(pApplication);
    return hr;
}
