//-------------------------------------------------------------------------------------------------
// <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.
    { L"freethreaded", L"Include_freethreaded" },
    { 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 blockedLauncher;

        if (SUCCEEDED(BalGetNumericVariable(L"BlockedLauncher", &blockedLauncher)) && blockedLauncher) {
            locKey = L"#(loc.Include_launcherRemove)";
        } else if (SUCCEEDED(BalGetNumericVariable(L"DetectedOldLauncher", &blockedLauncher)) && blockedLauncher) {
            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 BlockedLauncher)"
            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(10, 0, 0)) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows Server 2016 or later");
                return;
            } else if (IsWindowsVersionOrGreater(6, 2, 0)) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Server 2012");
            } else if (IsWindowsVersionOrGreater(6, 1, 1)) {
                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "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 2016 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_ERROR, "Detected Windows 8.1");
            } 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 10 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;
}
