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.
536 lines
13 KiB
536 lines
13 KiB
// Copyright (c) 2001 Microsoft Corporation
|
|
//
|
|
// File: PrintInstallationUnit.cpp
|
|
//
|
|
// Synopsis: Defines a PrintInstallationUnit
|
|
// This object has the knowledge for installing the
|
|
// printer services
|
|
//
|
|
// History: 02/06/2001 JeffJon Created
|
|
|
|
#include "pch.h"
|
|
#include "resource.h"
|
|
|
|
#include "PrintInstallationUnit.h"
|
|
|
|
|
|
// Finish page help
|
|
static PCWSTR CYS_PRINT_FINISH_PAGE_HELP = L"cys.chm::/print_server_role.htm";
|
|
static PCWSTR CYS_PRINT_MILESTONE_HELP = L"cys.chm::/print_server_role.htm#printsrvsummary";
|
|
static PCWSTR CYS_PRINT_AFTER_FINISH_HELP = L"cys.chm::/print_server_role.htm#printsrvcompletion";
|
|
|
|
PrintInstallationUnit::PrintInstallationUnit() :
|
|
printRoleResult(PRINT_SUCCESS),
|
|
forAllClients(false),
|
|
InstallationUnit(
|
|
IDS_PRINT_SERVER_TYPE,
|
|
IDS_PRINT_SERVER_DESCRIPTION,
|
|
IDS_PRINT_FINISH_TITLE,
|
|
IDS_PRINT_FINISH_UNINSTALL_TITLE,
|
|
IDS_PRINT_FINISH_MESSAGE,
|
|
IDS_PRINT_SUCCESS_NO_SHARES,
|
|
IDS_PRINT_UNINSTALL_MESSAGE,
|
|
IDS_PRINT_UNINSTALL_FAILED,
|
|
IDS_PRINT_UNINSTALL_WARNING,
|
|
IDS_PRINT_UNINSTALL_CHECKBOX,
|
|
CYS_PRINT_FINISH_PAGE_HELP,
|
|
CYS_PRINT_MILESTONE_HELP,
|
|
CYS_PRINT_AFTER_FINISH_HELP,
|
|
PRINTSERVER_SERVER)
|
|
{
|
|
LOG_CTOR(PrintInstallationUnit);
|
|
}
|
|
|
|
|
|
PrintInstallationUnit::~PrintInstallationUnit()
|
|
{
|
|
LOG_DTOR(PrintInstallationUnit);
|
|
}
|
|
|
|
|
|
InstallationReturnType
|
|
PrintInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::InstallService);
|
|
|
|
InstallationReturnType result = INSTALL_SUCCESS;
|
|
printRoleResult = PRINT_SUCCESS;
|
|
|
|
String resultText;
|
|
|
|
// Always execute the Add Printer Wizard
|
|
|
|
CYS_APPEND_LOG(String::load(IDS_PRINTER_WIZARD_CONFIG_LOG_TEXT));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
UpdateInstallationProgressText(hwnd, IDS_PRINT_PROGRESS_PRINTER_WIZARD);
|
|
|
|
if (ExecuteWizard(hwnd, CYS_PRINTER_WIZARD_NAME, resultText, hr))
|
|
{
|
|
// if there are shared printers, then we consider ourselves
|
|
// successful.
|
|
|
|
if (IsServiceInstalled())
|
|
{
|
|
CYS_APPEND_LOG(String::load(IDS_PRINT_SERVER_SUCCESSFUL));
|
|
}
|
|
else
|
|
{
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CYS_APPEND_LOG(String::load(IDS_PRINT_SERVER_UNSUCCESSFUL));
|
|
result = INSTALL_FAILURE;
|
|
printRoleResult = PRINT_WIZARD_RUN_NO_SHARES;
|
|
}
|
|
else
|
|
{
|
|
// The call to ExecuteWizard should have provided us with the
|
|
// error message.
|
|
|
|
ASSERT(!resultText.empty());
|
|
CYS_APPEND_LOG(resultText);
|
|
result = INSTALL_FAILURE;
|
|
|
|
if (HRESULT_CODE(hr) == ERROR_CANCELLED)
|
|
{
|
|
printRoleResult = PRINT_WIZARD_CANCELLED;
|
|
}
|
|
else
|
|
{
|
|
printRoleResult = PRINT_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// This should never be reached so assert if we get here
|
|
ASSERT(false);
|
|
|
|
LOG(L"Add Printer Wizard failed");
|
|
result = INSTALL_FAILURE;
|
|
|
|
printRoleResult = PRINT_FAILURE;
|
|
}
|
|
|
|
if (forAllClients)
|
|
{
|
|
// Now execute the Add Printer Driver Wizard
|
|
|
|
UpdateInstallationProgressText(hwnd, IDS_PRINT_PROGRESS_DRIVERS_WIZARD);
|
|
|
|
if (ExecuteWizard(hwnd, CYS_PRINTER_DRIVER_WIZARD_NAME, resultText, hr))
|
|
{
|
|
// NTRAID#NTBUG9-462079-2001/09/04-sburns
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ASSERT(resultText.empty());
|
|
|
|
CYS_APPEND_LOG(String::load(IDS_PRINTER_DRIVER_WIZARD_SUCCEEDED));
|
|
}
|
|
else
|
|
{
|
|
// The call to ExecuteWizard should have provided us with the
|
|
// error message.
|
|
|
|
ASSERT(!resultText.empty());
|
|
CYS_APPEND_LOG(resultText);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// This should never be reached so assert if we get here
|
|
ASSERT(false);
|
|
|
|
LOG(L"Add Printer Driver Wizard failed");
|
|
}
|
|
}
|
|
|
|
CYS_APPEND_LOG(L"\r\n");
|
|
LOG_INSTALL_RETURN(result);
|
|
|
|
return result;
|
|
}
|
|
|
|
HRESULT
|
|
PrintInstallationUnit::RemovePrinters(
|
|
PRINTER_INFO_5& printerInfo)
|
|
{
|
|
LOG_FUNCTION2(
|
|
PrintInstallationUnit::RemovePrinters,
|
|
printerInfo.pPrinterName);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
HANDLE printerHandle = 0;
|
|
|
|
// need to open the printer with admin access
|
|
|
|
PRINTER_DEFAULTS defaults = { 0, 0, PRINTER_ALL_ACCESS };
|
|
if (!OpenPrinter(
|
|
printerInfo.pPrinterName,
|
|
&printerHandle,
|
|
&defaults))
|
|
{
|
|
hr = Win::GetLastErrorAsHresult();
|
|
|
|
LOG(String::format(
|
|
L"Failed to open printer: hr = 0x%1!x!",
|
|
hr));
|
|
break;
|
|
}
|
|
|
|
// Now that we were able to open the printer
|
|
// delete it
|
|
|
|
if (!DeletePrinter(printerHandle))
|
|
{
|
|
hr = Win::GetLastErrorAsHresult();
|
|
|
|
LOG(String::format(
|
|
L"SetPrinter failed: hr = 0x%1!x!",
|
|
hr));
|
|
|
|
break;
|
|
}
|
|
|
|
} while (false);
|
|
|
|
LOG_HRESULT(hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
UnInstallReturnType
|
|
PrintInstallationUnit::UnInstallService(HANDLE logfileHandle, HWND hwnd)
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::UnInstallService);
|
|
|
|
UnInstallReturnType result = UNINSTALL_SUCCESS;
|
|
|
|
CYS_APPEND_LOG(String::load(IDS_LOG_PRINT_UNINSTALL_HEADER));
|
|
|
|
UpdateInstallationProgressText(hwnd, IDS_UNINSTALL_PRINT_PROGRESS);
|
|
|
|
// I am using level 5 here because it is the cheapest way to get
|
|
// the printer attributes
|
|
|
|
BYTE* printerInfo = 0;
|
|
DWORD bytesNeeded = 0;
|
|
DWORD numberOfPrinters = 0;
|
|
DWORD error = 0;
|
|
|
|
do
|
|
{
|
|
if (!EnumPrinters(
|
|
PRINTER_ENUM_LOCAL | PRINTER_ENUM_SHARED,
|
|
0,
|
|
5,
|
|
printerInfo,
|
|
bytesNeeded,
|
|
&bytesNeeded,
|
|
&numberOfPrinters))
|
|
{
|
|
error = GetLastError();
|
|
|
|
if (error == ERROR_INSUFFICIENT_BUFFER ||
|
|
error == ERROR_INVALID_USER_BUFFER)
|
|
{
|
|
|
|
// The buffer isn't large enough so allocate
|
|
// a new buffer and try again
|
|
|
|
LOG(L"Reallocating buffer and trying again...");
|
|
|
|
if (printerInfo)
|
|
{
|
|
delete[] printerInfo;
|
|
printerInfo = 0;
|
|
}
|
|
|
|
printerInfo = new BYTE[bytesNeeded];
|
|
if (!printerInfo)
|
|
{
|
|
LOG(L"Could not allocate printerInfo buffer!");
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
// Error occurred reading shared printers
|
|
|
|
result = UNINSTALL_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Remove the sharing bit from all the shared printers
|
|
|
|
LOG(String::format(
|
|
L"Found %1!d! printers",
|
|
numberOfPrinters));
|
|
|
|
PRINTER_INFO_5* printerInfoArray =
|
|
reinterpret_cast<PRINTER_INFO_5*>(printerInfo);
|
|
|
|
for (DWORD index = 0; index < numberOfPrinters; ++index)
|
|
{
|
|
HRESULT hr =
|
|
RemovePrinters(
|
|
printerInfoArray[index]);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
result = UNINSTALL_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (printerInfo)
|
|
{
|
|
delete[] printerInfo;
|
|
printerInfo = 0;
|
|
}
|
|
break;
|
|
}
|
|
} while (true);
|
|
|
|
if (result == UNINSTALL_SUCCESS)
|
|
{
|
|
CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_PRINT_SUCCESS));
|
|
}
|
|
else
|
|
{
|
|
CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_PRINT_FAILURE));
|
|
}
|
|
|
|
CYS_APPEND_LOG(L"\r\n");
|
|
|
|
LOG_UNINSTALL_RETURN(result);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool
|
|
PrintInstallationUnit::GetMilestoneText(String& message)
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::GetMilestoneText);
|
|
|
|
if (forAllClients)
|
|
{
|
|
message += String::load(IDS_PRINT_FINISH_ALL_CLIENTS);
|
|
}
|
|
else
|
|
{
|
|
message += String::load(IDS_PRINT_FINISH_W2K_CLIENTS);
|
|
}
|
|
|
|
LOG_BOOL(true);
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
PrintInstallationUnit::GetUninstallMilestoneText(String& message)
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::GetUninstallMilestoneText);
|
|
|
|
message = String::load(IDS_PRINT_UNINSTALL_TEXT);
|
|
|
|
LOG_BOOL(true);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
PrintInstallationUnit::SetClients(bool allclients)
|
|
{
|
|
LOG_FUNCTION2(
|
|
PrintInstallationUnit::SetClients,
|
|
allclients ? L"true" : L"false");
|
|
|
|
forAllClients = allclients;
|
|
}
|
|
|
|
int
|
|
PrintInstallationUnit::GetWizardStart()
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::GetWizardStart);
|
|
|
|
int wizardStart = IDD_PRINT_SERVER_PAGE;
|
|
|
|
bool installingRole = true;
|
|
|
|
if (IsServiceInstalled())
|
|
{
|
|
installingRole = false;
|
|
wizardStart = IDD_UNINSTALL_MILESTONE_PAGE;
|
|
}
|
|
|
|
SetInstalling(installingRole);
|
|
|
|
LOG(String::format(
|
|
L"wizardStart = %1!d!",
|
|
wizardStart));
|
|
|
|
return wizardStart;
|
|
}
|
|
|
|
String
|
|
PrintInstallationUnit::GetServiceDescription()
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::GetServiceDescription);
|
|
|
|
unsigned int description = descriptionID;
|
|
|
|
if (IsServiceInstalled())
|
|
{
|
|
description = IDS_PRINT_SERVER_DESCRIPTION_INSTALLED;
|
|
}
|
|
|
|
return String::load(description);
|
|
}
|
|
|
|
void
|
|
PrintInstallationUnit::ServerRoleLinkSelected(int linkIndex, HWND /*hwnd*/)
|
|
{
|
|
LOG_FUNCTION2(
|
|
PrintInstallationUnit::ServerRoleLinkSelected,
|
|
String::format(
|
|
L"linkIndex = %1!d!",
|
|
linkIndex));
|
|
|
|
if (IsServiceInstalled())
|
|
{
|
|
ASSERT(linkIndex == 0);
|
|
|
|
LaunchMYS();
|
|
}
|
|
else
|
|
{
|
|
ASSERT(linkIndex == 0);
|
|
|
|
LOG(L"Showing configuration help");
|
|
|
|
ShowHelp(CYS_PRINT_FINISH_PAGE_HELP);
|
|
}
|
|
}
|
|
|
|
String
|
|
PrintInstallationUnit::GetFinishText()
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::GetFinishText);
|
|
|
|
unsigned int messageID = finishMessageID;
|
|
|
|
if (installing)
|
|
{
|
|
if (printRoleResult == PRINT_SUCCESS)
|
|
{
|
|
messageID = finishMessageID;
|
|
}
|
|
else if (printRoleResult == PRINT_FAILURE)
|
|
{
|
|
messageID = IDS_PRINT_INSTALL_FAILED;
|
|
}
|
|
else
|
|
{
|
|
messageID = finishInstallFailedMessageID;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
messageID = finishUninstallMessageID;
|
|
}
|
|
|
|
return String::load(messageID);
|
|
}
|
|
|
|
void
|
|
PrintInstallationUnit::FinishLinkSelected(int linkIndex, HWND hwnd)
|
|
{
|
|
LOG_FUNCTION2(
|
|
PrintInstallationUnit::FinishLinkSelected,
|
|
String::format(
|
|
L"linkIndex = %1!d!",
|
|
linkIndex));
|
|
|
|
if (installing)
|
|
{
|
|
if (linkIndex == 0 &&
|
|
printRoleResult == PRINT_SUCCESS)
|
|
{
|
|
LOG("Showing after checklist");
|
|
|
|
ShowHelp(CYS_PRINT_AFTER_FINISH_HELP);
|
|
}
|
|
else if (linkIndex == 0)
|
|
{
|
|
LOG("Running Add Printer Wizard");
|
|
|
|
String unusedResult;
|
|
HRESULT unusedHr = S_OK;
|
|
ExecuteWizard(hwnd, CYS_PRINTER_WIZARD_NAME, unusedResult, unusedHr);
|
|
|
|
// NTRAID#NTBUG9-603366-2002/06/03-JeffJon-Close down CYS so
|
|
// that the user doesn't think they still failed even after
|
|
// running through the wizard again successfully from this
|
|
// link
|
|
|
|
Win::PropSheet_PressButton(
|
|
Win::GetParent(hwnd),
|
|
PSBTN_FINISH);
|
|
}
|
|
else if (linkIndex == 1)
|
|
{
|
|
LOG(L"Opening Printers and Faxes");
|
|
|
|
String fullPath =
|
|
FS::AppendPath(
|
|
Win::GetSystemDirectory(),
|
|
L"control.exe");
|
|
|
|
String commandline = L"printers";
|
|
|
|
MyCreateProcess(fullPath, commandline);
|
|
|
|
// NTRAID#NTBUG9-603366-2002/06/03-JeffJon-Close down CYS so
|
|
// that the user doesn't think they still failed even after
|
|
// running through the wizard again successfully from this
|
|
// link
|
|
|
|
Win::PropSheet_PressButton(
|
|
Win::GetParent(hwnd),
|
|
PSBTN_FINISH);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (IsServiceInstalled())
|
|
{
|
|
// There was a failure
|
|
|
|
// REVIEW_JEFFJON: From spec: ???
|
|
}
|
|
}
|
|
}
|
|
|
|
bool
|
|
PrintInstallationUnit::DoInstallerCheck(HWND /*hwnd*/) const
|
|
{
|
|
LOG_FUNCTION(PrintInstallationUnit::DoInstallerCheck);
|
|
|
|
// The printer wizards allow for more than one instance
|
|
// to run at the same time
|
|
|
|
bool result = false;
|
|
|
|
LOG_BOOL(result);
|
|
|
|
return result;
|
|
}
|
|
|