|
|
/*++
� 1998 Seagate Software, Inc. All rights reserved.
Module Name:
OptCom.cpp
Abstract:
Base Class for optional component work.
Author:
Rohde Wakefield [rohde] 09-Oct-1997
Revision History:
--*/
#include "stdafx.h"
#include "rsoptcom.h"
#include "OptCom.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRsOptCom::CRsOptCom() { TRACEFN( "CRsOptCom::CRsOptCom" ); }
CRsOptCom::~CRsOptCom() { TRACEFN( "CRsOptCom::CRsOptCom" );
}
DWORD CRsOptCom::SetupProc( IN LPCVOID /*ComponentId*/, IN LPCVOID SubcomponentId, IN UINT Function, IN UINT_PTR Param1, IN OUT PVOID Param2 ) { TRACEFN( "CRsOptCom::SetupProc" ); TRACE( L"Function = <%ls><%p>", StringFromFunction( Function ), Function );
SHORT subcomponentId = IdFromString( (LPCTSTR)SubcomponentId );
DWORD dwRet = 0;
switch( Function ) { case OC_PREINITIALIZE: dwRet = PreInitialize( (DWORD)Param1 ); break;
case OC_INIT_COMPONENT: dwRet = InitComponent( (PSETUP_INIT_COMPONENT)Param2 ); break;
case OC_SET_LANGUAGE: dwRet = (DWORD)SetLanguage( (WORD)Param1 ); break;
#ifndef _WIN64
case OC_QUERY_IMAGE: // Note: The casting of the return value from HBITMAP to DWORD is broken on IA64,
// however, Setup avoids calling with OC_QUERY_IMAGE on IA64, rather it uses OC_QUERY_IMAGE_EX
dwRet = (DWORD)QueryImage( subcomponentId, (SubComponentInfo)Param1, LOWORD(Param2), HIWORD(Param2) ); break; #endif
#ifdef _WIN64
case OC_QUERY_IMAGE_EX: dwRet = (DWORD)QueryImageEx( subcomponentId, (OC_QUERY_IMAGE_INFO *)Param1, (HBITMAP *)Param2 ); break; #endif
case OC_REQUEST_PAGES: dwRet = (DWORD)RequestPages( (WizardPagesType)Param1, (PSETUP_REQUEST_PAGES)Param2 ); break;
case OC_QUERY_CHANGE_SEL_STATE: dwRet = (DWORD)QueryChangeSelState( subcomponentId, Param1 != 0, (ULONG)((ULONG_PTR)Param2) ); break;
case OC_CALC_DISK_SPACE: dwRet = CalcDiskSpace( subcomponentId, Param1 != 0, (HDSKSPC)Param2 ); break;
case OC_QUEUE_FILE_OPS: dwRet = QueueFileOps( subcomponentId, (HSPFILEQ)Param2 ); break;
case OC_QUERY_STEP_COUNT: dwRet = (DWORD)QueryStepCount( subcomponentId ); break;
case OC_COMPLETE_INSTALLATION: dwRet = CompleteInstallation( subcomponentId ); break;
case OC_CLEANUP: CleanUp( ); break;
case OC_ABOUT_TO_COMMIT_QUEUE: dwRet = AboutToCommitQueue( subcomponentId ); break;
case OC_QUERY_SKIP_PAGE: dwRet = (DWORD)QuerySkipPage( (OcManagerPage)Param1 ); break;
case OC_QUERY_STATE: dwRet = (DWORD)QueryState( subcomponentId ); break;
case OC_NOTIFICATION_FROM_QUEUE: case OC_NEED_MEDIA: case OC_WIZARD_CREATED: break;
default: break; }
return( dwRet ); }
DWORD CRsOptCom::PreInitialize( IN DWORD /*Flags*/ ) { TRACEFNDW( "CRsOptCom::PreInitialize" );
#ifdef UNICODE
dwRet = OCFLAG_UNICODE; #else
dwRet = OCFLAG_ANSI; #endif
return( dwRet ); }
DWORD CRsOptCom::InitComponent( IN PSETUP_INIT_COMPONENT SetupInitComponent ) { TRACEFNDW( "CRsOptCom::InitComponent" );
dwRet = NO_ERROR;
m_OCManagerVersion = SetupInitComponent->OCManagerVersion; m_ComponentVersion = SetupInitComponent->ComponentVersion; m_OCInfHandle = SetupInitComponent->OCInfHandle; m_ComponentInfHandle = SetupInitComponent->ComponentInfHandle; m_SetupData = SetupInitComponent->SetupData; m_HelperRoutines = SetupInitComponent->HelperRoutines;
return( dwRet ); }
SubComponentState CRsOptCom::DetectInitialState( IN SHORT /*SubcomponentId*/ ) { TRACEFN( "CRsOptCom::DetectInitialState" ); SubComponentState retval = SubcompUseOcManagerDefault; return( retval ); }
SubComponentState CRsOptCom::QueryState( IN SHORT /*SubcomponentId*/ ) { TRACEFN( "CRsOptCom::QueryState" ); SubComponentState retval = SubcompUseOcManagerDefault; return( retval ); }
BOOL CRsOptCom::SetLanguage( WORD /*LangId*/ ) { TRACEFNBOOL( "CRsOptCom::SetLanguage" );
boolRet = TRUE; return( boolRet ); }
HBITMAP CRsOptCom::QueryImage( IN SHORT /*SubcomponentId*/, IN SubComponentInfo /*WhichImage*/, IN WORD /*Width*/, IN WORD /*Height*/ ) { TRACEFN( "CRsOptCom::QueryImage" ); HBITMAP retval = 0; return( retval ); }
BOOL CRsOptCom::QueryImageEx( IN SHORT /*SubcomponentId*/, IN OC_QUERY_IMAGE_INFO* /*pQueryImageInfo*/, OUT HBITMAP *phBitmap ) { TRACEFNBOOL( "CRsOptCom::QueryImageEx" );
if (phBitmap) { *phBitmap = NULL; }
boolRet = FALSE; return( boolRet ); }
LONG CRsOptCom::RequestPages( IN WizardPagesType /*Type*/, IN OUT PSETUP_REQUEST_PAGES /*RequestPages*/ ) { TRACEFNLONG( "CRsOptCom::RequestPages" ); lRet = 0; return( lRet ); }
BOOL CRsOptCom::QuerySkipPage( IN OcManagerPage /*Page*/ ) { TRACEFNBOOL( "CRsOptCom::QuerySkipPage" ); boolRet = FALSE; return( boolRet ); }
BOOL CRsOptCom::QueryChangeSelState( IN SHORT /*SubcomponentId*/, IN BOOL /*NewState*/, IN DWORD /*Flags*/ ) { TRACEFNBOOL( "CRsOptCom::QueryChangeSelState" ); boolRet = TRUE; return( boolRet ); }
DWORD CRsOptCom::CalcDiskSpace( IN SHORT /*SubcomponentId*/, IN BOOL /*AddSpace*/, IN HDSKSPC /*hDiskSpace*/ ) { TRACEFNDW( "CRsOptCom::CalcDiskSpace" ); dwRet = 0; return( dwRet ); }
DWORD CRsOptCom::QueueFileOps( IN SHORT /*SubcomponentId*/, IN HSPFILEQ /*hFileQueue*/ ) { TRACEFNDW( "CRsOptCom::QueueFileOps" ); dwRet = 0; return( dwRet ); }
LONG CRsOptCom::QueryStepCount( IN SHORT /*SubcomponentId*/ ) { TRACEFNLONG( "CRsOptCom::QueryStepCount" ); lRet = 0; return( lRet ); }
DWORD CRsOptCom::AboutToCommitQueue( IN SHORT /*SubcomponentId*/ ) { TRACEFNDW( "CRsOptCom::AboutToCommitQueue" ); dwRet = 0; return( dwRet ); }
DWORD CRsOptCom::CompleteInstallation( IN SHORT /*SubcomponentId*/ ) { TRACEFNDW( "CRsOptCom::CompleteInstallation" ); dwRet = 0; return( dwRet ); }
void CRsOptCom::CleanUp( void ) { TRACEFN( "CRsOptCom::CleanUp" ); }
DWORD CRsOptCom::DoCalcDiskSpace( IN BOOL AddSpace, IN HDSKSPC hDiskSpace, IN LPCTSTR SectionName ) { TRACEFNDW( "CRsOptCom::DoCalcDiskSpace" );
dwRet = NO_ERROR;
HINF hLayoutInf = SetupOpenInfFile( L"layout.inf", 0, INF_STYLE_WIN4 | INF_STYLE_OLDNT , 0 );
if( INVALID_HANDLE_VALUE == hLayoutInf) {
dwRet = GetLastError( ); TRACE( _T("CRsOptCom::AboutToCommitQueue Error opening LAYOUT.INF") );
}
if( NO_ERROR == dwRet ) {
if( AddSpace ) {
if( SetupAddInstallSectionToDiskSpaceList( hDiskSpace, m_ComponentInfHandle, hLayoutInf, SectionName, 0, 0 ) ) {
dwRet = GetLastError( );
}
} else {
if ( SetupRemoveInstallSectionFromDiskSpaceList( hDiskSpace, m_ComponentInfHandle, hLayoutInf, SectionName, 0, 0 ) ) {
dwRet = GetLastError( );
} } }
if( INVALID_HANDLE_VALUE != hLayoutInf) {
SetupCloseInfFile( hLayoutInf );
}
return( dwRet ); }
DWORD CRsOptCom::DoQueueFileOps( IN SHORT SubcomponentId, IN HSPFILEQ hFileQueue, IN LPCTSTR InstallSectionName, IN LPCTSTR UninstallSectionName ) { TRACEFNDW( "CRsOptCom::DoQueueFileOps" );
BOOL success = TRUE; RSOPTCOM_ACTION action = GetSubAction( SubcomponentId );
switch( action ) { case ACTION_INSTALL:
success = SetupInstallFilesFromInfSection( m_ComponentInfHandle, 0, hFileQueue, InstallSectionName, 0, SP_COPY_FORCE_NEWER ); break;
case ACTION_UNINSTALL:
success = SetupInstallFilesFromInfSection( m_ComponentInfHandle, 0, hFileQueue, UninstallSectionName, 0, 0 ); break;
case ACTION_UPGRADE:
success = SetupInstallFilesFromInfSection( m_ComponentInfHandle, 0, hFileQueue, InstallSectionName, 0, SP_COPY_FORCE_NEWER ); break;
}
dwRet = success ? NO_ERROR : GetLastError( ); return( dwRet ); }
DWORD CRsOptCom::DoRegistryOps( IN SHORT SubcomponentId, IN RSOPTCOM_ACTION actionForReg, IN LPCTSTR SectionName ) { TRACEFNDW( "CRsOptCom::DoRegistryOps" );
BOOL success = TRUE; RSOPTCOM_ACTION action = GetSubAction( SubcomponentId );
if ( action == actionForReg ) { success = SetupInstallFromInfSection( NULL, m_ComponentInfHandle, SectionName, SPINST_REGISTRY, NULL, NULL, 0, NULL, NULL, NULL, NULL ); }
dwRet = success ? NO_ERROR : GetLastError( ); return( dwRet ); }
LPCWSTR CRsOptCom::StringFromFunction( UINT Function ) { #define CASE_FUNCTION( a ) case a: return( OLESTR( #a ) );
switch( Function ) {
CASE_FUNCTION( OC_PREINITIALIZE ) CASE_FUNCTION( OC_INIT_COMPONENT ) CASE_FUNCTION( OC_SET_LANGUAGE ) CASE_FUNCTION( OC_QUERY_IMAGE ) CASE_FUNCTION( OC_REQUEST_PAGES ) CASE_FUNCTION( OC_QUERY_CHANGE_SEL_STATE ) CASE_FUNCTION( OC_CALC_DISK_SPACE ) CASE_FUNCTION( OC_QUEUE_FILE_OPS ) CASE_FUNCTION( OC_NOTIFICATION_FROM_QUEUE ) CASE_FUNCTION( OC_QUERY_STEP_COUNT ) CASE_FUNCTION( OC_COMPLETE_INSTALLATION ) CASE_FUNCTION( OC_CLEANUP ) CASE_FUNCTION( OC_QUERY_STATE ) CASE_FUNCTION( OC_NEED_MEDIA ) CASE_FUNCTION( OC_ABOUT_TO_COMMIT_QUEUE ) CASE_FUNCTION( OC_QUERY_SKIP_PAGE ) CASE_FUNCTION( OC_WIZARD_CREATED )
} return( TEXT( "Unknown" ) ); }
LPCWSTR CRsOptCom::StringFromPageType( WizardPagesType PageType ) { #define CASE_PAGETYPE( a ) case a: return( OLESTR( #a ) );
switch( PageType ) {
CASE_PAGETYPE( WizPagesWelcome ) CASE_PAGETYPE( WizPagesMode ) CASE_PAGETYPE( WizPagesEarly ) CASE_PAGETYPE( WizPagesPrenet ) CASE_PAGETYPE( WizPagesPostnet ) CASE_PAGETYPE( WizPagesLate ) CASE_PAGETYPE( WizPagesFinal ) CASE_PAGETYPE( WizPagesTypeMax )
} return( TEXT( "Unknown" ) ); }
LPCWSTR CRsOptCom::StringFromAction( RSOPTCOM_ACTION Action ) { #define CASE_ACTION( a ) case a: return( OLESTR( #a ) );
switch( Action ) {
CASE_ACTION( ACTION_NONE ) CASE_ACTION( ACTION_INSTALL ) CASE_ACTION( ACTION_UNINSTALL ) CASE_ACTION( ACTION_REINSTALL ) CASE_ACTION( ACTION_UPGRADE )
} return( TEXT( "Unknown" ) ); }
RSOPTCOM_ACTION CRsOptCom::GetSubAction( SHORT SubcomponentId ) { TRACEFN( "CRsOptCom::GetSubAction" );
RSOPTCOM_ACTION retval = ACTION_NONE; UINT setupMode = GetSetupMode( ); DWORDLONG operationFlags = m_SetupData.OperationFlags;
BOOL originalState = QuerySelectionState( SubcomponentId, OCSELSTATETYPE_ORIGINAL ); BOOL currentState = QuerySelectionState( SubcomponentId, OCSELSTATETYPE_CURRENT );
if( !originalState && currentState ) {
retval = ACTION_INSTALL;
} else if( originalState && !currentState ) {
retval = ACTION_UNINSTALL;
} else if( ( SETUPOP_NTUPGRADE & operationFlags ) && originalState && currentState ) {
retval = ACTION_UPGRADE;
}
TRACE( L"SubcomponentId = <%hd>, originalState = <%hs>, currentState = <%hs>", SubcomponentId, RsBoolAsString( originalState ), RsBoolAsString( currentState ) ); TRACE( L"OperationsFlags = <0x%0.16I64x>, setupMode = <0x%p>", operationFlags, setupMode ); TRACE( L"retval = <%ls>", StringFromAction( retval ) ); return( retval ); }
HRESULT CRsOptCom::CreateLink( LPCTSTR lpszProgram, LPCTSTR lpszArgs, LPTSTR lpszLink, LPCTSTR lpszDir, LPCTSTR lpszDesc, int nItemDescId, int nDescId, LPCTSTR lpszIconPath, int iIconIndex ) { TRACEFNHR( "CRsOptCom::CreateLink" );
CComPtr<IShellLink> pShellLink;
TCHAR szSystemPath[MAX_PATH]; TCHAR szResourceString[MAX_PATH+128]; UINT uLen = 0;
szSystemPath[0] = _T('\0'); szResourceString[0] = _T('\0');
// CoInitialize must be called before this
// Get a pointer to the IShellLink interface.
hrRet = CoInitialize( 0 ); if( SUCCEEDED( hrRet ) ) { hrRet = CoCreateInstance( CLSID_ShellLink, 0, CLSCTX_SERVER, IID_IShellLink, (void**)&pShellLink ); if( SUCCEEDED( hrRet ) ) {
CComPtr<IPersistFile> pPersistFile;
// Set the path to the shortcut target, and add the description.
pShellLink->SetPath( lpszProgram ); pShellLink->SetArguments( lpszArgs ); pShellLink->SetWorkingDirectory( lpszDir ); pShellLink->SetIconLocation( lpszIconPath, iIconIndex );
// Description should be set using the resource id in order to support MUI
uLen = GetSystemDirectory(szSystemPath, MAX_PATH); if ((uLen > 0) && (uLen < MAX_PATH)) { wsprintf(szResourceString, TEXT("@%s\\setup\\RsOptCom.dll,-%d"), szSystemPath, nDescId); pShellLink->SetDescription(szResourceString); } else { // Set English description
pShellLink->SetDescription(lpszDesc); }
// Query IShellLink for the IPersistFile interface for saving the
// shortcut in persistent storage.
hrRet = pShellLink->QueryInterface( IID_IPersistFile, (void**)&pPersistFile );
if( SUCCEEDED( hrRet ) ) {
CComBSTR wsz = lpszLink;
// Save the link by calling IPersistFile::Save.
hrRet = pPersistFile->Save( wsz, TRUE );
if( SUCCEEDED(hrRet) && (uLen > 0) && (uLen < MAX_PATH)) {
// Shortcut created - set MUI name.
wsprintf(szResourceString, TEXT("%s\\setup\\RsOptCom.dll"), szSystemPath);
hrRet = SHSetLocalizedName(lpszLink, szResourceString, nItemDescId); } }
}
CoUninitialize(); }
return( hrRet ); }
BOOL CRsOptCom::DeleteLink( LPTSTR lpszShortcut ) { TRACEFNBOOL( "CRsOptCom::DeleteLink" );
boolRet = TRUE;
TCHAR szFile[_MAX_PATH]; SHFILEOPSTRUCT fos;
ZeroMemory( szFile, sizeof(szFile) ); lstrcpy( szFile, lpszShortcut );
if( DoesFileExist( szFile ) ) {
ZeroMemory( &fos, sizeof(fos) ); fos.hwnd = NULL; fos.wFunc = FO_DELETE; fos.pFrom = szFile; fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION; SHFileOperation( &fos ); }
return( boolRet ); }
HRESULT CRsOptCom::GetGroupPath( int nFolder, LPTSTR szPath ) { TRACEFNHR( "CRsOptCom::GetGroupPath" ); szPath[0] = _T('\0'); hrRet = SHGetFolderPath( 0, nFolder | CSIDL_FLAG_CREATE, 0, 0, szPath ); TRACE( L"szPath = <%ls>", szPath ); return( hrRet ); }
void CRsOptCom::AddItem( int nFolder, LPCTSTR szItemDesc, LPCTSTR szProgram, LPCTSTR szArgs, LPCTSTR szDir, LPCTSTR szDesc, int nItemDescId, int nDescId, LPCTSTR szIconPath, int iIconIndex ) { TRACEFN( "CRsOptCom::AddItem" );
TCHAR szPath[_MAX_PATH];
if( S_OK == GetGroupPath( nFolder, szPath ) ) {
lstrcat( szPath, _T("\\") ); lstrcat( szPath, szItemDesc ); lstrcat( szPath, _T(".lnk") );
CreateLink( szProgram, szArgs, szPath, szDir, szDesc, nItemDescId, nDescId, szIconPath, iIconIndex ); } }
void CRsOptCom::DeleteItem( int nFolder, LPCTSTR szAppName ) { TRACEFN( "CRsOptCom::DeleteItem" );
TCHAR szPath[_MAX_PATH];
if( S_OK == GetGroupPath( nFolder, szPath ) ) {
lstrcat( szPath, _T("\\") ); lstrcat( szPath, szAppName ); lstrcat( szPath, _T(".lnk") ); DeleteLink( szPath ); } }
typedef HRESULT (WINAPI *PFN_DLLENTRYPOINT)( void );
HRESULT CRsOptCom::CallDllEntryPoint( LPCTSTR pszDLLName, LPCSTR pszEntryPoint ) { TRACEFNHR( "CRsOptCom::CallDllEntryPoint" ); TRACE( _T("Dll <%s> Func <%hs>"), pszDLLName, pszEntryPoint );
HINSTANCE hDLL = 0; PFN_DLLENTRYPOINT pfnEntryPoint;
try {
hDLL = LoadLibrary( pszDLLName ); RsOptAffirmStatus( hDLL );
pfnEntryPoint = (PFN_DLLENTRYPOINT)GetProcAddress( hDLL, pszEntryPoint ); RsOptAffirmStatus( pfnEntryPoint );
hrRet = pfnEntryPoint();
} RsOptCatch( hrRet );
if( hDLL ) FreeLibrary( hDLL );
return( hrRet ); }
|