2020-09-30 17:12:29 +02:00

594 lines
13 KiB
C++

/*++
Copyright (c) 1996 Microsoft Corporation
All rights reserved.
Module Name:
Instarch.cxx
Abstract:
Installs alternate drivers for other architectures.
Author:
Steve Kiraly (SteveKi) 18-Jan-1996
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include <setupapi.h>
#include "splsetup.h"
#include "psetup.hxx"
#include "drvver.hxx"
#include "instarch.hxx"
/********************************************************************
Architecture.
********************************************************************/
//
// Constructor
//
TInstallArchitecture::
TInstallArchitecture(
VOID
) : _hWnd( NULL ),
_hDlg( NULL ),
_hCtl( NULL ),
_cForeignDrivers( 0 ),
_pdwForeignDrivers( NULL ),
_pSelectedDriverInfo( NULL ),
_hSetupDrvSetupParams( NULL ),
_pPSetup( NULL ),
_iControlId( 0 ),
_dwCurrentDriver( NULL ),
_bValid( TRUE ),
_bFullList( FALSE ),
_bEnabled( TRUE )
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::ctor\n" ) );
}
//
// Destructor
//
TInstallArchitecture::
~TInstallArchitecture(
VOID
)
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::dtor\n" ) );
//
// Release the selected driver information.
//
if( _pSelectedDriverInfo )
_pPSetup->PSetupDestroySelectedDriverInfo( _pSelectedDriverInfo );
//
// Release the driver setup parameter handle.
//
if( _hSetupDrvSetupParams )
_pPSetup->PSetupDestroyDrvSetupParams( _hSetupDrvSetupParams );
//
// Release any foreign architectures selections.
//
FreeMem( _pdwForeignDrivers );
//
// Release the setup library.
//
delete _pPSetup;
}
//
// Return valid object indicator.
//
BOOL
TInstallArchitecture::
bValid(
VOID
)
{
return _bValid;
}
//
// Refresh the install architecture UI. When a new driver is
// choosen a refresh is needed to insure we display the correct
// list.
//
BOOL
TInstallArchitecture::
bRefreshUI(
IN LPCTSTR pszModelName
)
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::bRefreshUI\n" ) );
return bSetUI(_hDlg,
_iControlId,
_strServerName,
pszModelName,
_bFullList );
}
//
// Set the install architecture UI.
// i.e. currently this is a multi-selection list box.
//
BOOL
TInstallArchitecture::
bSetUI(
IN HWND hDlg,
IN INT iControlId,
IN LPCTSTR pszServerName,
IN LPCTSTR pszModelName,
IN BOOL bDisplayFullDriverList
)
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::bSetUI\n" ) );
DBGMSG( DBG_TRACE, ( "Server Name " TSTR " \n" , DBGSTR( pszServerName ) ) );
DBGMSG( DBG_TRACE, ( "Model Name " TSTR "\n", pszModelName ) );
_hCtl = GetDlgItem( hDlg, iControlId );
_iControlId = iControlId;
_hDlg = hDlg;
_hWnd = hDlg;
_bFullList = bDisplayFullDriverList;
//
// Make a copy of the server name. We need a copy since the
// we reference it outside of the context of this routine.
// Note a null server name indicates a local machine.
//
if( !_strServerName.bUpdate( pszServerName ) ){
vDisableAndInvalidate();
return FALSE;
}
//
// Make a copy of the model name. We need a copy since the
// we reference it outside of the context of this routine.
//
if( !_strModelName.bUpdate( pszModelName ) ){
vDisableAndInvalidate();
return FALSE;
}
//
// Attempt to get servers architecute / driver version.
//
if( !bGetCurrentDriver( pszFixServerName(),
&_dwCurrentDriver ) ){
vDisableAndInvalidate();
return FALSE;
}
//
// Instantiate the setup library.
//
if( !_pPSetup ){
_pPSetup = new TPSetup;
//
// Insure the library object is valid.
//
if( !VALID_PTR( _pPSetup ) ){
vDisableAndInvalidate();
return FALSE;
}
}
//
// Display the driver selection list.
//
if( !bDisplaySelectionList() ){
vDisableAndInvalidate();
return FALSE;
}
_bValid = TRUE;
return TRUE;
}
//
// Make the object as invalid and disable its controls.
//
VOID
TInstallArchitecture::
vDisableAndInvalidate(
VOID
)
{
_bValid = FALSE;
vDisable();
}
//
// FixServerName. This routine converts our string object server name
// to the Win32 API server name. A server name which is the numm string
// should be passed as a null pointer to indicate the local machine.
//
LPCTSTR
TInstallArchitecture::
pszFixServerName(
VOID
) const
{
return _strServerName.bEmpty() ? NULL : (LPCTSTR)_strServerName;
}
//
// Display the driver selection list.
//
BOOL
TInstallArchitecture::
bDisplaySelectionList(
VOID
)
{
//
// Define order of drivers in list box.
//
static DWORD adwDrivers[] = {
DRIVER_WIN95,
DRIVER_X86_2,
DRIVER_MIPS_2,
DRIVER_ALPHA_2,
DRIVER_PPC_2,
DRIVER_X86_1,
DRIVER_MIPS_1,
DRIVER_ALPHA_1,
DRIVER_PPC_1,
DRIVER_X86_0,
DRIVER_MIPS_0,
DRIVER_ALPHA_0,
};
DWORD dwDriverOffset;
COUNT cDriver;
TCHAR szText[kStrMax];
TString strDriver;
TString strInstalled;
TStatusB bStatus;
UINT i;
//
// Load the string "(installed)" from the resource file.
//
bStatus DBGCHK = strInstalled.bLoadString( ghInst, IDS_DRIVER_INSTALLED );
if( !bStatus ){
return FALSE;
}
ListBox_ResetContent( _hCtl );
for( i = 0, cDriver = 0; i< COUNTOF( adwDrivers ); ++i ){
dwDriverOffset = adwDrivers[i];
//
// If we are to display the full list including the native driver.
//
if( !_bFullList ){
if( dwDriverOffset == _dwCurrentDriver ){
continue;
}
}
//
// Load the string driver name string from the resource file.
//
bStatus DBGCHK = strDriver.bLoadString( ghInst, IDS_DRIVER_BASE + dwDriverOffset );
if( !bStatus ){
return FALSE;
}
//
// A temp buffer is need because the string class does not
// have a concatenation operator.
//
lstrcpy( szText, strDriver );
//
// If the driver is installed, tell the user.
//
if( _pPSetup->PSetupIsDriverInstalled(
pszFixServerName(),
_strModelName,
GetDriverPlatform( dwDriverOffset ),
GetDriverVersion( dwDriverOffset ) ) ){
SPLASSERT( lstrlen( strDriver ) + lstrlen( strInstalled ) < COUNTOF( szText ) );
lstrcat( szText, strInstalled );
}
ListBox_AddString( _hCtl, szText );
ListBox_SetItemData( _hCtl, cDriver, dwDriverOffset );
//
// Driver sucessfully added.
//
++cDriver;
}
return TRUE;
}
//
// Read the install architecture UI. This routine reads the
// multi-selection list box items and creates a list. The
// bInstall routine will take the currently selected items and
// install the drivers. This is a two stage process because the
// property page or wizard page completion code will decide to install
// or not install the alternate driver architectures. The goal here
// is to isolate the data structures used for tracking the multi-selection
// list box from the user of the class. Inaddition to the tracking of the
// data structures this class will deal with the memory allocation and
// dealocation to prevent any chance of a memory leak.
//
BOOL
TInstallArchitecture::
bReadUI(
VOID
)
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::bReadUI\n" ) );
BOOL bStatus = FALSE;
PDWORD pdwSelected = NULL;
COUNT cSelected = 0;
COUNT i;
//
// Get the selected items from the list box.
//
cSelected = ListBox_GetSelCount( _hCtl );
//
// If nothing is selected exit.
//
if ( !cSelected ){
DBGMSG( DBG_TRACE, ( "Nothing is Selected.\n" ) );
goto Fail;
}
//
// Allocate space for the selection list.
//
pdwSelected = (PDWORD)AllocMem( cSelected * sizeof( *pdwSelected ));
if( !pdwSelected ){
vShowResourceError( _hDlg );
DBGMSG( DBG_WARN, ( "Failed selection allocation.\n" ) );
goto Fail;
}
//
// Get the selected items.
//
if( LB_ERR == ListBox_GetSelItems( _hCtl, cSelected, pdwSelected )){
vShowUnexpectedError( _hDlg, IDS_ERR_PRINTER_PROP_TITLE );
DBGMSG( DBG_WARN, ( "Selection get Items failed.\n" ) );
goto Fail;
}
//
// Transform _pdwDrivers into version/arch.
//
for( i = 0; i < cSelected; ++i ){
pdwSelected[i] = ListBox_GetItemData( _hCtl, pdwSelected[i] );
}
//
// Free any previous selections.
//
FreeMem( _pdwForeignDrivers );
//
// Save count and pointer to new selection.
//
_cForeignDrivers = cSelected;
_pdwForeignDrivers = pdwSelected;
//
// NULL to fall through.
//
pdwSelected = NULL;
bStatus = TRUE;
Fail:
FreeMem( pdwSelected );
return bStatus;
}
//
// Enable the TInstallArchitecture UI. Usually invoked when
// the user chooses to share this printer.
//
VOID
TInstallArchitecture::
vEnable(
VOID
)
{
SPLASSERT( _bValid );
_bEnabled = TRUE;
EnableWindow( _hCtl, TRUE );
}
//
// Disable the TInstallArchitecture UI. Usually invoked when
// the user chooses not to share this printer.
//
VOID
TInstallArchitecture::
vDisable(
VOID
)
{
SPLASSERT( _bValid );
_bEnabled = FALSE;
EnableWindow( _hCtl, FALSE );
}
//
// This routine will installed the selected drivers. Usually this
// routine will be invoked at property sheet completion time.
//
BOOL
TInstallArchitecture::
bInstall(
VOID
)
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::bInstall\n" ) );
//
// If there are no driver selected
// or the list box is disabled return success.
//
if( !_cForeignDrivers &&
!_bEnabled ){
return TRUE;
}
BOOL bStatus = TRUE;
//
// Run through the foreign drivers and install all of them.
//
for( UINT i = 0; i < _cForeignDrivers; ++i ){
DBGMSG( DBG_TRACE, ( "Install Driver %d\n", _pdwForeignDrivers[i] ) );
if( !bInstallDriver( _pdwForeignDrivers[i] ) ){
bStatus = FALSE;
break;
}
}
return bStatus;
}
//
// This routine will installed driver for this platform.
//
BOOL
TInstallArchitecture::
bInstallCurrent(
VOID
)
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::bInstallCurrent\n" ) );
return bInstallDriver( _dwCurrentDriver );
}
//
// Install the selected drivers.
//
BOOL
TInstallArchitecture::
bInstallDriver(
IN DWORD dwDriver
)
{
DBGMSG( DBG_TRACE, ( "TInstallArchitecture::bInstallDriver\n" ) );
//
// Get the the SetupDrvSetupParams handle, if it has not
// already been acquired.
//
if( _hSetupDrvSetupParams == NULL ){
_hSetupDrvSetupParams = _pPSetup->PSetupCreateDrvSetupParams();
if( !_hSetupDrvSetupParams ){
DBGMSG( DBG_WARN, ( "TInstallArchitecture TPrinterDriverSetup::bInstance failed.\n" ) );
return FALSE;
}
}
//
// Get the the Selected Drvier info pointer form our existing
// model name, if it has not already been acquired.
//
if( _pSelectedDriverInfo == NULL ){
_pSelectedDriverInfo = _pPSetup->PSetupDriverInfoFromName( _hSetupDrvSetupParams, _strModelName );
if( !_pSelectedDriverInfo ){
DBGMSG( DBG_WARN, ( "TInstallArchitecture: PSetupDriverInfoFromName failed %d\n", GetLastError( )));
return FALSE;
}
}
//
// Get the architecture name from the resource file.
//
TString strDrvArchName;
if( !strDrvArchName.bLoadString( ghInst, IDS_DRIVER_BASE + dwDriver ) ){
DBGMSG( DBG_WARN, ( "TInstallArchitecture::bInstalled LoadString IDS_DRIVER_BASE failed %d\n", GetLastError( )));
return FALSE;
}
DBGMSG( DBG_TRACE, ( "Installing driver " TSTR "\n", (LPCTSTR)strDrvArchName ) );
//
// Install the printer driver.
//
TStatus Status;
Status DBGCHK = _pPSetup->PSetupInstallPrinterDriver(_hSetupDrvSetupParams,
_pSelectedDriverInfo,
GetDriverPlatform( dwDriver ),
bIs3xDriver( dwDriver ),
pszFixServerName(),
IsWindow( _hWnd ) ? _hWnd : NULL,
(LPCTSTR)strDrvArchName );
if( Status != ERROR_SUCCESS ){
//
// If the user hit cancel exit else return an error.
//
if( Status != ERROR_CANCELLED ){
DBGMSG( DBG_WARN, ( "TInstallArchitecture: PSetupCopyFilesAndInstallPrinterDriver failed %d\n", Status ));
return FALSE;
}
}
return TRUE;
}