Leaked source code of windows server 2003
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

// 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(&currentTime, 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);
}
}
}