You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
489 lines
12 KiB
489 lines
12 KiB
// Copyright (c) 2002 Microsoft Corporation
|
|
//
|
|
// File: InstallationProgressPage.cpp
|
|
//
|
|
// Synopsis: Defines the Installation Progress Page for the CYS
|
|
// wizard. This page shows the progress of the installation
|
|
// through a progress bar and changing text
|
|
//
|
|
// History: 01/16/2002 JeffJon Created
|
|
|
|
|
|
#include "pch.h"
|
|
#include "resource.h"
|
|
|
|
#include "InstallationUnitProvider.h"
|
|
#include "InstallationProgressPage.h"
|
|
|
|
static PCWSTR PROGRESS_PAGE_HELP = L"cys.chm::/cys_topnode.htm";
|
|
|
|
InstallationProgressPage::InstallationProgressPage()
|
|
:
|
|
CYSWizardPage(
|
|
IDD_PROGRESS_PAGE,
|
|
IDS_PROGRESS_TITLE,
|
|
IDS_PROGRESS_SUBTITLE,
|
|
0,
|
|
false)
|
|
{
|
|
LOG_CTOR(InstallationProgressPage);
|
|
}
|
|
|
|
InstallationProgressPage::InstallationProgressPage(
|
|
int dialogResID,
|
|
int titleResID,
|
|
int subtitleResID)
|
|
:
|
|
CYSWizardPage(
|
|
dialogResID,
|
|
titleResID,
|
|
subtitleResID,
|
|
0,
|
|
false)
|
|
{
|
|
LOG_CTOR(InstallationProgressPage);
|
|
}
|
|
|
|
|
|
InstallationProgressPage::~InstallationProgressPage()
|
|
{
|
|
LOG_DTOR(InstallationProgressPage);
|
|
}
|
|
|
|
void
|
|
TimeStampTheLog(HANDLE logfileHandle)
|
|
{
|
|
LOG_FUNCTION(TimeStampTheLog);
|
|
|
|
ASSERT(logfileHandle);
|
|
|
|
SYSTEMTIME currentTime;
|
|
::ZeroMemory(¤tTime, sizeof(SYSTEMTIME));
|
|
|
|
Win::GetLocalTime(currentTime);
|
|
|
|
String date;
|
|
HRESULT unused = Win::GetDateFormat(
|
|
currentTime,
|
|
date);
|
|
ASSERT(SUCCEEDED(unused));
|
|
|
|
String time;
|
|
unused = Win::GetTimeFormat(
|
|
currentTime,
|
|
time);
|
|
ASSERT(SUCCEEDED(unused));
|
|
|
|
String logDate = String::format(
|
|
L"(%1 %2)\r\n",
|
|
date.c_str(),
|
|
time.c_str());
|
|
|
|
CYS_APPEND_LOG(logDate);
|
|
}
|
|
|
|
// Private window messages for sending the state of the finished thread
|
|
|
|
const UINT InstallationProgressPage::CYS_THREAD_SUCCESS = WM_USER + 1001;
|
|
const UINT InstallationProgressPage::CYS_THREAD_FAILED = WM_USER + 1002;
|
|
const UINT InstallationProgressPage::CYS_THREAD_USER_CANCEL = WM_USER + 1003;
|
|
const UINT InstallationProgressPage::CYS_PROGRESS_UPDATE = WM_USER + 1004;
|
|
|
|
void _cdecl
|
|
installationProc(void* p)
|
|
{
|
|
if (!p)
|
|
{
|
|
ASSERT(p);
|
|
return;
|
|
}
|
|
|
|
InstallationProgressPage* page =
|
|
reinterpret_cast<InstallationProgressPage*>(p);
|
|
|
|
if (!page)
|
|
{
|
|
ASSERT(page);
|
|
return;
|
|
}
|
|
|
|
unsigned int finishMessage = InstallationProgressPage::CYS_THREAD_SUCCESS;
|
|
|
|
// Initialize COM for this thread
|
|
|
|
HRESULT hr = ::CoInitialize(0);
|
|
if (FAILED(hr))
|
|
{
|
|
ASSERT(SUCCEEDED(hr));
|
|
return;
|
|
}
|
|
|
|
// Open the log file and pass the handle to the installation unit
|
|
|
|
// Create the log file
|
|
|
|
bool logFileAvailable = false;
|
|
String logName;
|
|
HANDLE logfileHandle = AppendLogFile(
|
|
CYS_LOGFILE_NAME,
|
|
logName);
|
|
if (logfileHandle &&
|
|
logfileHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
LOG(String::format(L"New log file was created: %1", logName.c_str()));
|
|
logFileAvailable = true;
|
|
|
|
// Time stamp the log
|
|
|
|
TimeStampTheLog(logfileHandle);
|
|
}
|
|
else
|
|
{
|
|
LOG(L"Unable to create the log file!!!");
|
|
logFileAvailable = false;
|
|
}
|
|
|
|
// Install the current Installation Unit. This may be one or more services depending on the
|
|
// path that was taken through the wizard
|
|
|
|
InstallationUnit& installationUnit =
|
|
InstallationUnitProvider::GetInstance().GetCurrentInstallationUnit();
|
|
|
|
// NTRAID#NTBUG-604592-2002/04/23-JeffJon-I am calling Installing here
|
|
// instead of IsServiceInstalled so that we perform the action that
|
|
// the user selected on the role selection page. The state of
|
|
// IsServiceInstalled could have changed since they hit Next on that
|
|
// page.
|
|
|
|
if (!installationUnit.Installing())
|
|
{
|
|
UnInstallReturnType uninstallResult =
|
|
installationUnit.UnInstallService(logfileHandle, page->GetHWND());
|
|
|
|
// Set the uninstall result so that the finish page can read it
|
|
|
|
installationUnit.SetUninstallResult(uninstallResult);
|
|
|
|
if (UNINSTALL_SUCCESS == uninstallResult)
|
|
{
|
|
LOG(L"Service uninstalled successfully");
|
|
}
|
|
else if (UNINSTALL_NO_CHANGES == uninstallResult)
|
|
{
|
|
LOG(L"No changes");
|
|
LOG(L"Not logging results");
|
|
}
|
|
else if (UNINSTALL_SUCCESS_REBOOT == uninstallResult)
|
|
{
|
|
LOG(L"Service uninstalled successfully");
|
|
LOG(L"Not logging results because reboot was initiated");
|
|
}
|
|
else if (UNINSTALL_SUCCESS_PROMPT_REBOOT == uninstallResult)
|
|
{
|
|
LOG(L"Service uninstalled successfully");
|
|
LOG(L"Prompting user to reboot");
|
|
|
|
if (-1 == SetupPromptReboot(
|
|
0,
|
|
page->GetHWND(),
|
|
FALSE))
|
|
{
|
|
LOG(String::format(
|
|
L"Failed to reboot: hr = %1!x!",
|
|
Win::GetLastErrorAsHresult()));
|
|
}
|
|
|
|
// At this point the system should be shutting down
|
|
// so don't do anything else
|
|
|
|
}
|
|
else
|
|
{
|
|
LOG(L"Service failed to uninstall");
|
|
}
|
|
|
|
// Add an additional line at the end of the log file
|
|
// only if we are not rebooting. All the reboot
|
|
// scenarios require additional logging to the same
|
|
// entry.
|
|
|
|
if (uninstallResult != UNINSTALL_SUCCESS_REBOOT)
|
|
{
|
|
CYS_APPEND_LOG(L"\r\n");
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
InstallationReturnType installResult =
|
|
installationUnit.CompletePath(logfileHandle, page->GetHWND());
|
|
|
|
// Set the installation result so that the finish
|
|
// page can read it
|
|
|
|
installationUnit.SetInstallResult(installResult);
|
|
|
|
if (INSTALL_SUCCESS == installResult)
|
|
{
|
|
LOG(L"Service installed successfully");
|
|
}
|
|
else if (INSTALL_NO_CHANGES == installResult)
|
|
{
|
|
LOG(L"No changes");
|
|
LOG(L"Not logging results");
|
|
}
|
|
else if (INSTALL_SUCCESS_REBOOT == installResult)
|
|
{
|
|
LOG(L"Service installed successfully");
|
|
LOG(L"Not logging results because reboot was initiated");
|
|
}
|
|
else if (INSTALL_SUCCESS_PROMPT_REBOOT == installResult)
|
|
{
|
|
LOG(L"Service installed successfully");
|
|
LOG(L"Prompting user to reboot");
|
|
|
|
if (-1 == SetupPromptReboot(
|
|
0,
|
|
page->GetHWND(),
|
|
FALSE))
|
|
{
|
|
LOG(String::format(
|
|
L"Failed to reboot: hr = %1!x!",
|
|
Win::GetLastErrorAsHresult()));
|
|
}
|
|
|
|
// At this point the system should be shutting down
|
|
// so don't do anything else
|
|
|
|
}
|
|
else
|
|
{
|
|
LOG(L"Service failed to install");
|
|
}
|
|
|
|
// Add an additional line at the end of the log file
|
|
// only if we are not rebooting. All the reboot
|
|
// scenarios require additional logging to the same
|
|
// entry.
|
|
|
|
if (installResult != INSTALL_SUCCESS_REBOOT)
|
|
{
|
|
CYS_APPEND_LOG(L"\r\n");
|
|
}
|
|
}
|
|
|
|
// Close the log file
|
|
|
|
Win::CloseHandle(logfileHandle);
|
|
|
|
Win::SendMessage(
|
|
page->GetHWND(),
|
|
finishMessage,
|
|
0,
|
|
0);
|
|
|
|
CoUninitialize();
|
|
}
|
|
|
|
void
|
|
InstallationProgressPage::OnInit()
|
|
{
|
|
LOG_FUNCTION(InstallationProgressPage::OnInit);
|
|
|
|
CYSWizardPage::OnInit();
|
|
|
|
// Disable all the buttons on the page. The
|
|
// user shouldn't really be able to do anything on
|
|
// this page. Just sit back relax and watch the
|
|
// installation happen.
|
|
|
|
Win::PropSheet_SetWizButtons(
|
|
Win::GetParent(hwnd),
|
|
0);
|
|
|
|
SetCancelState(false);
|
|
|
|
// Start up the animation
|
|
|
|
Win::Animate_Open(
|
|
Win::GetDlgItem(hwnd, IDC_ANIMATION),
|
|
MAKEINTRESOURCE(IDR_PROGRESS_AVI));
|
|
|
|
// Start up another thread that will perform the operations
|
|
// and post messages back to the page to update the UI
|
|
|
|
_beginthread(installationProc, 0, this);
|
|
|
|
}
|
|
|
|
bool
|
|
InstallationProgressPage::OnMessage(
|
|
UINT message,
|
|
WPARAM wparam,
|
|
LPARAM lparam)
|
|
{
|
|
// LOG_FUNCTION(InstallationProgressPage::OnMessage);
|
|
|
|
bool result = false;
|
|
|
|
switch (message)
|
|
{
|
|
case CYS_PROGRESS_UPDATE:
|
|
{
|
|
String update = reinterpret_cast<PCWSTR>(wparam);
|
|
|
|
Win::SetDlgItemText(
|
|
hwnd,
|
|
IDC_STEP_TEXT_STATIC,
|
|
update);
|
|
}
|
|
break;
|
|
|
|
case CYS_THREAD_USER_CANCEL:
|
|
// shouldCancel = true;
|
|
|
|
// fall through...
|
|
|
|
case CYS_THREAD_SUCCESS:
|
|
case CYS_THREAD_FAILED:
|
|
{
|
|
Win::Animate_Stop(Win::GetDlgItem(hwnd, IDC_ANIMATION));
|
|
|
|
InstallationUnit& installationUnit =
|
|
InstallationUnitProvider::GetInstance().
|
|
GetCurrentInstallationUnit();
|
|
|
|
bool continueToNext = false;
|
|
|
|
if (installationUnit.Installing())
|
|
{
|
|
InstallationReturnType installResult =
|
|
installationUnit.GetInstallResult();
|
|
|
|
if (installResult != INSTALL_SUCCESS_REBOOT &&
|
|
installResult != INSTALL_SUCCESS_PROMPT_REBOOT)
|
|
{
|
|
continueToNext = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnInstallReturnType uninstallResult =
|
|
installationUnit.GetUnInstallResult();
|
|
|
|
if (uninstallResult != UNINSTALL_SUCCESS_REBOOT &&
|
|
uninstallResult != UNINSTALL_SUCCESS_PROMPT_REBOOT)
|
|
{
|
|
continueToNext = true;
|
|
}
|
|
}
|
|
|
|
if (continueToNext)
|
|
{
|
|
Win::PropSheet_PressButton(
|
|
Win::GetParent(hwnd),
|
|
PSBTN_NEXT);
|
|
}
|
|
|
|
result = true;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
result =
|
|
CYSWizardPage::OnMessage(
|
|
message,
|
|
wparam,
|
|
lparam);
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int
|
|
InstallationProgressPage::Validate()
|
|
{
|
|
LOG_FUNCTION(InstallationProgressPage::Validate);
|
|
|
|
int nextPage = IDD_FINISH_PAGE;
|
|
|
|
LOG(String::format(
|
|
L"nextPage = %1!d!",
|
|
nextPage));
|
|
|
|
return nextPage;
|
|
}
|
|
|
|
bool
|
|
InstallationProgressPage::OnQueryCancel()
|
|
{
|
|
LOG_FUNCTION(InstallationProgressPage::OnQueryCancel);
|
|
|
|
// Don't allow cancel
|
|
|
|
Win::SetWindowLongPtr(
|
|
hwnd,
|
|
DWLP_MSGRESULT,
|
|
TRUE);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
InstallationProgressPage::OnSetActive()
|
|
{
|
|
LOG_FUNCTION(InstallationProgressPage::OnSetActive);
|
|
|
|
SetCancelState(false);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
InstallationProgressPage::OnKillActive()
|
|
{
|
|
LOG_FUNCTION(InstallationProgressPage::OnKillActive);
|
|
|
|
SetCancelState(true);
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
InstallationProgressPage::SetCancelState(bool enable)
|
|
{
|
|
LOG_FUNCTION(InstallationProgressPage::SetCancelState);
|
|
|
|
// Set the state of the button
|
|
|
|
Win::EnableWindow(
|
|
Win::GetDlgItem(
|
|
Win::GetParent(hwnd),
|
|
IDCANCEL),
|
|
enable);
|
|
|
|
|
|
// Set the state of the X in the upper right corner
|
|
|
|
HMENU menu = GetSystemMenu(GetParent(hwnd), FALSE);
|
|
|
|
if (menu)
|
|
{
|
|
if (enable)
|
|
{
|
|
EnableMenuItem(
|
|
menu,
|
|
SC_CLOSE,
|
|
MF_BYCOMMAND | MF_ENABLED);
|
|
}
|
|
else
|
|
{
|
|
EnableMenuItem(
|
|
menu,
|
|
SC_CLOSE,
|
|
MF_BYCOMMAND | MF_GRAYED);
|
|
}
|
|
}
|
|
}
|