//-------------------------------------------------------------------------------------------------
// <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 LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_PATH = L"LaunchTarget";
static const LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID = L"LaunchTargetElevatedId";
static const LPCWSTR PYBA_VARIABLE_LAUNCH_ARGUMENTS = L"LaunchArguments";
static const LPCWSTR PYBA_VARIABLE_LAUNCH_HIDDEN = L"LaunchHidden";
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_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"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_ALL_USERS_BUTTON,
    ID_INSTALL_JUST_FOR_ME_BUTTON,
    ID_INSTALL_CUSTOM_BUTTON,
    ID_INSTALL_SIMPLE_BUTTON,
    ID_INSTALL_CANCEL_BUTTON,
    
    // Customize Page
    ID_TARGETDIR_EDITBOX,
    ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX,
    ID_CUSTOM_INSTALL_ALL_USERS_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_LAUNCH_BUTTON,
    ID_SUCCESS_TEXT,
    ID_SUCCESS_RESTART_TEXT,
    ID_SUCCESS_RESTART_BUTTON,
    ID_SUCCESS_CANCEL_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_ALL_USERS_BUTTON, L"InstallAllUsersButton" },
    { ID_INSTALL_JUST_FOR_ME_BUTTON, L"InstallJustForMeButton" },
    { ID_INSTALL_CUSTOM_BUTTON, L"InstallCustomButton" },
    { ID_INSTALL_SIMPLE_BUTTON, L"InstallSimpleButton" },
    { ID_INSTALL_CANCEL_BUTTON, L"InstallCancelButton" },

    { ID_TARGETDIR_EDITBOX, L"TargetDir" },
    { ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, L"AssociateFiles" },
    { ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, L"InstallAllUsers" },
    { 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_LAUNCH_BUTTON, L"LaunchButton" },
    { ID_SUCCESS_TEXT, L"SuccessText" },
    { ID_SUCCESS_RESTART_TEXT, L"SuccessRestartText" },
    { ID_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" },
    { ID_SUCCESS_CANCEL_BUTTON, L"SuccessCancelButton" },

    { 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" },
};

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) {
            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_ALL_USERS_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;
        BOOL checked;
        WCHAR wzPath[MAX_PATH] = { };
        BROWSEINFOW browseInfo = { };
        PIDLIST_ABSOLUTE pidl = nullptr;
        HRESULT hr = S_OK;

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

        // Install commands
        case ID_INSTALL_SIMPLE_BUTTON:
            hr = BalGetStringVariable(L"TargetDir", &targetDir);
            if (FAILED(hr) || !targetDir || !*targetDir) {
                LONGLONG installAll;
                if (SUCCEEDED(BalGetNumericVariable(L"InstallAllUsers", &installAll)) && installAll) {
                    hr = BalGetStringVariable(L"DefaultAllUsersTargetDir", &defaultDir);
                    BalExitOnFailure(hr, "Failed to get the default all users install directory");
                } else {
                    hr = BalGetStringVariable(L"DefaultJustForMeTargetDir", &defaultDir);
                    BalExitOnFailure(hr, "Failed to get the default per-user install directory");
                }

                if (!defaultDir || !*defaultDir) {
                    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);
                ReleaseStr(targetDir);
                BalExitOnFailure(hr, "Failed to set install target directory");
            } else {
                ReleaseStr(targetDir);
            }

            OnPlan(BOOTSTRAPPER_ACTION_INSTALL);
            break;

        case ID_INSTALL_ALL_USERS_BUTTON:
            SavePageSettings();
            
            hr = _engine->SetVariableNumeric(L"InstallAllUsers", 1);
            ExitOnFailure(hr, L"Failed to set install scope");

            hr = _engine->SetVariableNumeric(L"CompileAll", 1);
            ExitOnFailure(hr, L"Failed to set compile all setting");

            hr = BalGetStringVariable(L"DefaultAllUsersTargetDir", &defaultDir);
            BalExitOnFailure(hr, "Failed to get the default all users install directory");

            if (!defaultDir || !*defaultDir) {
                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);
            ReleaseStr(targetDir);
            BalExitOnFailure(hr, "Failed to set install target directory");

            OnPlan(BOOTSTRAPPER_ACTION_INSTALL);
            break;

        case ID_INSTALL_JUST_FOR_ME_BUTTON:
            SavePageSettings();

            if (!QueryElevateForCrtInstall()) {
                break;
            }

            hr = _engine->SetVariableNumeric(L"InstallAllUsers", 0);
            ExitOnFailure(hr, L"Failed to set install scope");

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

            hr = BalGetStringVariable(L"DefaultJustForMeTargetDir", &defaultDir);
            BalExitOnFailure(hr, "Failed to get the default per-user install directory");

            if (!defaultDir || !*defaultDir) {
                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);
            ReleaseStr(targetDir);
            BalExitOnFailure(hr, "Failed to set install target directory");

            OnPlan(BOOTSTRAPPER_ACTION_INSTALL);
            break;

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

        case ID_INSTALL_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 = BalGetStringVariable(L"TargetDir", &targetDir);
            if (SUCCEEDED(hr)) {
                // TODO: Check whether directory exists and contains another installation
                ReleaseStr(targetDir);
            }

            checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX);
            if (!checked && !QueryElevateForCrtInstall()) {
                break;
            }

            OnPlan(_command.action);
            break;

        case ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX:
            hr = BalGetNumericVariable(L"WixBundleElevated", &elevated);
            checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX);
            ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, checked && (FAILED(hr) || !elevated));
            ThemeControlEnable(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, !checked);
            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"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;
        }

    LExit:
        return;
    }

    void InstallPage_Show() {
        // Ensure the All Users install button has a UAC shield
        LONGLONG elevated, installAll;

        if (FAILED(BalGetNumericVariable(L"WixBundleElevated", &elevated))) {
            elevated = 0;
        }

        ThemeControlElevates(_theme, ID_INSTALL_ALL_USERS_BUTTON, !elevated);

        if (SUCCEEDED(BalGetNumericVariable(L"InstallAllUsers", &installAll)) && installAll) {
            ThemeControlElevates(_theme, ID_INSTALL_SIMPLE_BUTTON, !elevated);
        }
    }

    void Custom1Page_Show() {
    }

    void Custom2Page_Show() {
        HRESULT hr;
        LONGLONG installAll, elevated, includeLauncher;
        
        if (FAILED(BalGetNumericVariable(L"WixBundleElevated", &elevated))) {
            elevated = 0;
        }
        if (SUCCEEDED(BalGetNumericVariable(L"InstallAllUsers", &installAll))) {
            ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, installAll && !elevated);
            ThemeShowControl(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, SW_HIDE);
        } else {
            installAll = 0;
            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 or launch button should be enabled.
        BOOL showRestartButton = FALSE;
        BOOL launchTargetExists = FALSE;
        LOC_STRING *successText = nullptr;
        HRESULT hr = S_OK;
        
        if (_restartRequired) {
            if (BOOTSTRAPPER_RESTART_PROMPT == _command.restart) {
                showRestartButton = TRUE;
            }
        } else if (ThemeControlExists(_theme, ID_LAUNCH_BUTTON)) {
            launchTargetExists = BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_PATH);
        }

        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_LAUNCH_BUTTON, launchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < _plannedAction);
        ThemeControlEnable(_theme, ID_SUCCESS_RESTART_TEXT, showRestartButton);
        ThemeControlEnable(_theme, ID_SUCCESS_RESTART_BUTTON, showRestartButton);
    }

    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);
    }


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) 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) {
            _downgrading = TRUE;
        }

        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)) {
            hrStatus = EvaluateConditions();
        }

        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*/) {
        if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hrStatus) {
            //try with ShelExec next time
            OnClickLaunchButton();
        } else {
            ::PostMessageW(_hWnd, WM_CLOSE, 0, 0);
        }
    }


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.");

        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;
    }


    //
    // 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.");

        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 (_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 = { };

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

        // 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 = (HBRUSH)(COLOR_WINDOW+1);
        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_LAUNCH_BUTTON:
                pBA->OnClickLaunchButton();
                return 0;

            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_CTLCOLORBTN:
            if (pBA) {
                HWND button = (HWND)lParam;
                DWORD style = GetWindowLong(button, GWL_STYLE) & BS_TYPEMASK;
                if (style == BS_COMMANDLINK || style == BS_DEFCOMMANDLINK) {
                    return (LRESULT)pBA->_theme->rgFonts[pBA->_theme->dwFontId].hBackground;
                }
            }
            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;
            LPWSTR name = nullptr;
            LOC_STRING *locText = 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(&name, L"#(loc.%lsNote)", pControl->sczName);
                if (SUCCEEDED(hr)) {
                    hr = LocGetString(_wixLoc, name, &locText);
                    ReleaseStr(name);
                    if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) {
                        hr = BalFormatString(locText->wzText, &text);
                        if (SUCCEEDED(hr) && text && text[0]) {
                            ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text);
                            ReleaseStr(text);
                            text = nullptr;
                        }
                    }
                }
                hr = S_OK;
            }

            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);
    }


    //
    // 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 (_downgrading && 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];

            // 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)) {
                        ThemeControlEnable(_theme, pControl->wId, 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 (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, controlState, -1, L"disable", -1)) {
                            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Disable control %ls", pControl->sczName);
                            ThemeControlEnable(_theme, pControl->wId, 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);
                        }
                    }
                    StrFree(controlState);
                }
                StrFree(controlName);
            }

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


    //
    // OnClickLaunchButton - launch the app from the success page.
    //
    void OnClickLaunchButton() {
        HRESULT hr = S_OK;
        LPWSTR sczUnformattedLaunchTarget = nullptr;
        LPWSTR sczLaunchTarget = nullptr;
        LPWSTR sczLaunchTargetElevatedId = nullptr;
        LPWSTR sczUnformattedArguments = nullptr;
        LPWSTR sczArguments = nullptr;
        int nCmdShow = SW_SHOWNORMAL;

        hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_PATH, &sczUnformattedLaunchTarget);
        BalExitOnFailure1(hr, "Failed to get launch target variable '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_PATH);

        hr = BalFormatString(sczUnformattedLaunchTarget, &sczLaunchTarget);
        BalExitOnFailure1(hr, "Failed to format launch target variable: %ls", sczUnformattedLaunchTarget);

        if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID)) {
            hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID, &sczLaunchTargetElevatedId);
            BalExitOnFailure1(hr, "Failed to get launch target elevated id '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID);
        }

        if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_ARGUMENTS)) {
            hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_ARGUMENTS, &sczUnformattedArguments);
            BalExitOnFailure1(hr, "Failed to get launch arguments '%ls'.", PYBA_VARIABLE_LAUNCH_ARGUMENTS);
        }

        if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_HIDDEN)) {
            nCmdShow = SW_HIDE;
        }

        if (sczLaunchTargetElevatedId && !_triedToLaunchElevated) {
            _triedToLaunchElevated = TRUE;
            hr = _engine->LaunchApprovedExe(_hWnd, sczLaunchTargetElevatedId, sczUnformattedArguments, 0);
            if (FAILED(hr)) {
                BalLogError(hr, "Failed to launch elevated target: %ls", sczLaunchTargetElevatedId);

                //try with ShelExec next time
                OnClickLaunchButton();
            }
        } else {
            if (sczUnformattedArguments) {
                hr = BalFormatString(sczUnformattedArguments, &sczArguments);
                BalExitOnFailure1(hr, "Failed to format launch arguments variable: %ls", sczUnformattedArguments);
            }

            hr = ShelExec(sczLaunchTarget, sczArguments, L"open", nullptr, nCmdShow, _hWnd, nullptr);
            BalExitOnFailure1(hr, "Failed to launch target: %ls", sczLaunchTarget);

            ::PostMessageW(_hWnd, WM_CLOSE, 0, 0);
        }

    LExit:
        StrSecureZeroFreeString(sczArguments);
        ReleaseStr(sczUnformattedArguments);
        ReleaseStr(sczLaunchTargetElevatedId);
        StrSecureZeroFreeString(sczLaunchTarget);
        ReleaseStr(sczUnformattedLaunchTarget);

        return;
    }


    //
    // 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 (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 IsCrtInstalled() {
        if (_crtInstalledToken > 0) {
            return TRUE;
        } else if (_crtInstalledToken == 0) {
            return FALSE;
        }
        
        // Check whether at least CRT v10.0.9924.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.
        // However, since the WU package does not include vcruntime140.dll, we
        // still install that ourselves.
        LPCWSTR crtFile = L"api-ms-win-crt-runtime-l1-1-0.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 >= 0x26C40000) {
            result = TRUE;
        }
        
        free(pData);
        _crtInstalledToken = result ? 1 : 0;
        return result;
    }

    BOOL QueryElevateForCrtInstall() {
        // Called to prompt the user that even though they think they won't need
        // to elevate, they actually will because of the CRT install.
        if (IsCrtInstalled()) {
            // CRT is already installed - no need to prompt
            return TRUE;
        }
        
        LONGLONG elevated;
        HRESULT hr = BalGetNumericVariable(L"WixBundleElevated", &elevated);
        if (SUCCEEDED(hr) && elevated) {
            // Already elevated - no need to prompt
            return TRUE;
        }

        LOC_STRING *locStr;
        hr = LocGetString(_wixLoc, L"#(loc.ElevateForCRTInstall)", &locStr);
        if (FAILED(hr)) {
            BalLogError(hr, "Failed to get ElevateForCRTInstall string");
            return FALSE;
        }
        return ::MessageBoxW(_hWnd, locStr->wzText, _theme->sczCaption, MB_YESNO) != IDNO;
    }

    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);
            }
        }
    }


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;

        _downgrading = FALSE;
        _restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
        _restartRequired = FALSE;
        _allowRestart = FALSE;

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

        _overridableVariables = nullptr;
        _taskbarList = nullptr;
        _taskbarButtonCreatedMessage = UINT_MAX;
        _taskbarButtonOK = FALSE;
        _showingInternalUIThisPackage = FALSE;
        _triedToLaunchElevated = 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 _downgrading;
    BOOTSTRAPPER_APPLY_RESTART _restartResult;
    BOOL _restartRequired;
    BOOL _allowRestart;

    BOOL _suppressDowngradeFailure;
    BOOL _suppressRepair;
    BOOL _modifying;

    int _crtInstalledToken;

    STRINGDICT_HANDLE _overridableVariables;

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

    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;
}
