754 lines
17 KiB
C++
754 lines
17 KiB
C++
|
/*++
|
|||
|
|
|||
|
<EFBFBD> 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 );
|
|||
|
}
|
|||
|
|