594 lines
13 KiB
C++
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;
|
|
|
|
}
|
|
|