windows-nt/Source/XPSP1/NT/sdktools/appverif/selapp.cpp
2020-09-26 16:20:57 +08:00

639 lines
16 KiB
C++

//
// Application Verifier UI
// Copyright (c) Microsoft Corporation, 2001
//
//
//
// module: SelApp.cpp
// author: DMihai
// created: 02/22/2001
//
// Description:
//
// "Select applications to be verified" wizard page class.
//
#include "stdafx.h"
#include "appverif.h"
#include "SelApp.h"
#include "AVGlobal.h"
#include "Setting.h"
#include "AVUtil.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Help IDs
//
static DWORD MyHelpIds[] =
{
0, 0
};
/////////////////////////////////////////////////////////////////////////////
// CSelectAppPage property page
IMPLEMENT_DYNCREATE(CSelectAppPage, CAppverifPage)
CSelectAppPage::CSelectAppPage() : CAppverifPage(CSelectAppPage::IDD)
{
//{{AFX_DATA_INIT(CSelectAppPage)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
CSelectAppPage::~CSelectAppPage()
{
}
void CSelectAppPage::DoDataExchange(CDataExchange* pDX)
{
CAppverifPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSelectAppPage)
DDX_Control(pDX, IDC_SELECTAPPS_LIST, m_AppList);
DDX_Control(pDX, IDC_SELECTAPPS_NEXTDESCR_STATIC, m_NextDescription);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSelectAppPage, CAppverifPage)
//{{AFX_MSG_MAP(CSelectAppPage)
ON_MESSAGE( WM_HELP, OnHelp )
ON_WM_CONTEXTMENU()
ON_BN_CLICKED(IDC_SELECTAPPS_ADD_BUTTON, OnAddButton)
ON_BN_CLICKED(IDC_SELECTAPPS_REMOVE_BUTTON, OnRemoveButton)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
ULONG CSelectAppPage::GetDialogId() const
{
return IDD_APPLICATION_PAGE;
}
/////////////////////////////////////////////////////////////////////////////
VOID CSelectAppPage::SetupListHeader()
{
CString strTitle;
CRect rectWnd;
LVCOLUMN lvColumn;
//
// The list's rectangle
//
m_AppList.GetClientRect( &rectWnd );
ZeroMemory( &lvColumn,
sizeof( lvColumn ) );
lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_LEFT;
//
// Column 0
//
VERIFY( strTitle.LoadString( IDS_FILE_NAME ) );
lvColumn.iSubItem = 0;
lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
lvColumn.cx = (int)( rectWnd.Width() * 0.17 );
VERIFY( m_AppList.InsertColumn( 0, &lvColumn ) != -1 );
strTitle.ReleaseBuffer();
//
// Column 1
//
VERIFY( strTitle.LoadString( IDS_FILE_VERSION ) );
lvColumn.iSubItem = 1;
lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
lvColumn.cx = (int)( rectWnd.Width() * 0.15 );
VERIFY( m_AppList.InsertColumn( 1, &lvColumn ) != -1 );
strTitle.ReleaseBuffer();
//
// Column 2
//
VERIFY( strTitle.LoadString( IDS_COMPANY ) );
lvColumn.iSubItem = 2;
lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
lvColumn.cx = (int)( rectWnd.Width() * 0.30 );
VERIFY( m_AppList.InsertColumn( 2, &lvColumn ) != -1 );
strTitle.ReleaseBuffer();
//
// Column 3
//
VERIFY( strTitle.LoadString( IDS_PRODUCT_NAME ) );
lvColumn.iSubItem = 3;
lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
lvColumn.cx = (int)( rectWnd.Width() * 0.38 );
VERIFY( m_AppList.InsertColumn( 3, &lvColumn ) != -1 );
strTitle.ReleaseBuffer();
}
/////////////////////////////////////////////////////////////////////////////
VOID CSelectAppPage::SortTheList()
{
}
/////////////////////////////////////////////////////////////////////////////
INT CSelectAppPage::AddListItem( INT_PTR nIndexInDataArray,
CApplicationData *pAppData )
{
INT nActualIndex;
LVITEM lvItem;
ASSERT_VALID( pAppData );
nActualIndex = -1;
ZeroMemory( &lvItem, sizeof( lvItem ) );
//
// LVITEM's member pszText is not a const pointer
// so we need to GetBuffer here :-(
//
//
// Sub-item 0 - file name
//
lvItem.pszText = pAppData->m_strExeFileName.GetBuffer(
pAppData->m_strExeFileName.GetLength() + 1 );
if( NULL == lvItem.pszText )
{
goto Done;
}
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.lParam = nIndexInDataArray;
lvItem.iItem = m_AppList.GetItemCount();
nActualIndex = m_AppList.InsertItem( &lvItem );
pAppData->m_strExeFileName.ReleaseBuffer();
if( nActualIndex < 0 )
{
//
// Could not add an item in the list - give up
//
goto Done;
}
//
// Sub-item 1 - file version
//
lvItem.pszText = pAppData->m_strFileVersion.GetBuffer(
pAppData->m_strFileVersion.GetLength() + 1 );
if( NULL == lvItem.pszText )
{
goto Done;
}
lvItem.mask = LVIF_TEXT;
lvItem.iItem = nActualIndex;
lvItem.iSubItem = 1;
VERIFY( m_AppList.SetItem( &lvItem ) );
pAppData->m_strFileVersion.ReleaseBuffer();
//
// Sub-item 2 - provider
//
lvItem.pszText = pAppData->m_strCompanyName.GetBuffer(
pAppData->m_strCompanyName.GetLength() + 1 );
if( NULL == lvItem.pszText )
{
goto Done;
}
lvItem.mask = LVIF_TEXT;
lvItem.iItem = nActualIndex;
lvItem.iSubItem = 2;
VERIFY( m_AppList.SetItem( &lvItem ) );
pAppData->m_strCompanyName.ReleaseBuffer();
//
// Sub-item 3 - product name
//
lvItem.pszText = pAppData->m_strProductName.GetBuffer(
pAppData->m_strProductName.GetLength() + 1 );
if( NULL == lvItem.pszText )
{
goto Done;
}
lvItem.mask = LVIF_TEXT;
lvItem.iItem = nActualIndex;
lvItem.iSubItem = 3;
VERIFY( m_AppList.SetItem( &lvItem ) );
pAppData->m_strProductName.ReleaseBuffer();
Done:
//
// All done
//
return nActualIndex;
}
/////////////////////////////////////////////////////////////////////////////
VOID CSelectAppPage::FillTheList()
{
INT_PTR nVerifiedApps;
INT_PTR nCrtVerifiedApp;
CApplicationData *pAppData;
nVerifiedApps = g_NewSettings.m_aApplicationData.GetSize();
for( nCrtVerifiedApp = 0; nCrtVerifiedApp < nVerifiedApps; nCrtVerifiedApp +=1 )
{
pAppData = g_NewSettings.m_aApplicationData.GetAt( nCrtVerifiedApp );
ASSERT_VALID( pAppData );
AddListItem( nCrtVerifiedApp,
pAppData );
}
}
/////////////////////////////////////////////////////////////////////////////
// CSelectAppPage message handlers
/////////////////////////////////////////////////////////////
LONG CSelectAppPage::OnHelp( WPARAM wParam, LPARAM lParam )
{
LONG lResult = 0;
LPHELPINFO lpHelpInfo = (LPHELPINFO)lParam;
::WinHelp(
(HWND) lpHelpInfo->hItemHandle,
g_szAVHelpFile,
HELP_WM_HELP,
(DWORD_PTR) MyHelpIds );
return lResult;
}
/////////////////////////////////////////////////////////////////////////////
void CSelectAppPage::OnContextMenu(CWnd* pWnd, CPoint point)
{
::WinHelp(
pWnd->m_hWnd,
g_szAVHelpFile,
HELP_CONTEXTMENU,
(DWORD_PTR) MyHelpIds );
}
/////////////////////////////////////////////////////////////////////////////
BOOL CSelectAppPage::OnWizardFinish()
{
BOOL bExitTheApp;
INT nResponse;
ASSERT( AVSettingsTypeStandard == g_NewSettings.m_SettingsType );
if( m_AppList.GetItemCount() > 0 )
{
//
// Have at least one app selected to be verified
//
bExitTheApp = AVSaveNewSettings();
}
else
{
//
// No apps in the list
//
nResponse = AVMesssageBoxFromResource( IDS_SELECT_AT_LEAST_ONE_APP,
MB_YESNO | MB_ICONQUESTION );
//
// The user might choose to delete all settings here
//
bExitTheApp = ( nResponse == IDYES ) && AVSaveNewSettings();
}
return bExitTheApp;
}
/////////////////////////////////////////////////////////////////////////////
BOOL CSelectAppPage::OnSetActive()
{
ASSERT_VALID( m_pParentSheet );
ASSERT( AVSettingsTypeStandard == g_NewSettings.m_SettingsType );
m_pParentSheet->SetWizardButtons( PSWIZB_BACK | PSWIZB_FINISH );
//
// Display the description of the next step
//
AVSetWindowText( m_NextDescription, IDS_SELAPP_FINISH_DESCR );
return CAppverifPage::OnSetActive();
}
/////////////////////////////////////////////////////////////////////////////
BOOL CSelectAppPage::OnInitDialog()
{
CAppverifPage::OnInitDialog();
m_AppList.SetExtendedStyle(
LVS_EX_FULLROWSELECT | m_AppList.GetExtendedStyle() );
//
// Setup our list and fill it out if we already have something in the app names array
//
SetupListHeader();
FillTheList();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
/////////////////////////////////////////////////////////////////////////////
// CSelectAppPage message handlers
#define VRF_MAX_CHARS_FOR_OPEN 4096
void CSelectAppPage::OnAddButton()
{
POSITION pos;
DWORD dwOldMaxFileName = 0;
DWORD dwErrorCode;
INT nFileNameStartIndex;
INT nNewListItemIndex;
INT_PTR nResult;
INT_PTR nNewAppDataIndex;
CApplicationData *pNewAppData;
TCHAR *szFilesBuffer = NULL;
TCHAR *szOldFilesBuffer = NULL;
CString strPathName;
CString strFileName;
CFileDialog fileDlg(
TRUE, // open file
_T( "exe" ), // default extension
NULL, // no initial file name
OFN_ALLOWMULTISELECT | // multiple selection
OFN_HIDEREADONLY | // hide the "open read-only" checkbox
OFN_NONETWORKBUTTON | // no network button
OFN_NOTESTFILECREATE | // don't test for write protection, a full disk, etc.
OFN_SHAREAWARE, // don't check the existance of file with OpenFile
_T( "Executable Files (*.exe)|*.exe||" ) ); // only one filter
//
// Check the max length for the returned string
//
if( fileDlg.m_ofn.nMaxFile < VRF_MAX_CHARS_FOR_OPEN )
{
//
// Allocate a new buffer for the file names
//
szFilesBuffer = new TCHAR[ VRF_MAX_CHARS_FOR_OPEN ];
szFilesBuffer[ 0 ] = (TCHAR)0;
if( szFilesBuffer != NULL )
{
//
// Save the old buffer address and length
//
dwOldMaxFileName = fileDlg.m_ofn.nMaxFile;
szOldFilesBuffer = fileDlg.m_ofn.lpstrFile;
//
// Set the new buffer address and length
//
fileDlg.m_ofn.lpstrFile = szFilesBuffer;
fileDlg.m_ofn.nMaxFile = VRF_MAX_CHARS_FOR_OPEN;
}
}
fileDlg.m_ofn.lpstrTitle = (LPCTSTR) g_strAppName;
//
// Show the file selection dialog
//
nResult = fileDlg.DoModal();
switch( nResult )
{
case IDOK:
break;
case IDCANCEL:
goto cleanup;
default:
dwErrorCode = CommDlgExtendedError();
if( dwErrorCode == FNERR_BUFFERTOOSMALL )
{
AVErrorResourceFormat(
IDS_TOO_MANY_FILES_SELECTED );
}
else
{
AVErrorResourceFormat(
IDS_CANNOT_OPEN_FILES,
dwErrorCode );
}
goto cleanup;
}
//
// Parse all the selected files and try to enable them for verification
//
pos = fileDlg.GetStartPosition();
while( pos != NULL )
{
//
// Get the full path for the next file
//
strPathName = fileDlg.GetNextPathName( pos );
//
// Split only the file name, without the directory
//
nFileNameStartIndex = strPathName.ReverseFind( _T( '\\' ) );
if( nFileNameStartIndex < 0 )
{
//
// This shoudn't happen but you never know :-)
//
nFileNameStartIndex = 0;
}
else
{
//
// Skip the backslash
//
nFileNameStartIndex += 1;
}
strFileName = strPathName.Right( strPathName.GetLength() - nFileNameStartIndex );
//
// Try to add this app to our global list
//
if( g_NewSettings.m_aApplicationData.IsFileNameInList( strFileName ) )
{
AVErrorResourceFormat( IDS_APP_IS_ALREADY_IN_LIST,
(LPCTSTR) strFileName );
}
else
{
nNewAppDataIndex = g_NewSettings.m_aApplicationData.AddNewAppData( strFileName,
strPathName,
g_dwNewSettingBits );
if( nNewAppDataIndex >= 0 )
{
//
// Add a new item to our list corresponding to this app
//
pNewAppData = g_NewSettings.m_aApplicationData.GetAt( nNewAppDataIndex );
ASSERT_VALID( pNewAppData );
nNewListItemIndex = AddListItem( nNewAppDataIndex,
pNewAppData );
if( nNewListItemIndex >= 0 )
{
m_AppList.EnsureVisible( nNewListItemIndex, TRUE );
}
}
}
}
cleanup:
if( szFilesBuffer != NULL )
{
fileDlg.m_ofn.nMaxFile = dwOldMaxFileName;
fileDlg.m_ofn.lpstrFile = szOldFilesBuffer;
delete szFilesBuffer;
}
}
/////////////////////////////////////////////////////////////////////////////
void CSelectAppPage::OnRemoveButton()
{
int nItems;
int nCrtItem;
INT_PTR nIndexInDataArray;
INT_PTR nElementsToRemove;
INT_PTR nCrtElement;
INT_PTR nCrtIndexToAdjust;
CPtrArray aIndexesToRemove;
//
// Add the index of all the apps to remove from the
// g_NewSettings.m_aApplicationData array in aIndexesToRemove.
//
nItems = m_AppList.GetItemCount();
for( nCrtItem = 0; nCrtItem < nItems; nCrtItem++ )
{
if( m_AppList.GetItemState( nCrtItem, LVIS_SELECTED ) &
LVIS_SELECTED )
{
nIndexInDataArray = (UINT)m_AppList.GetItemData( nCrtItem );
ASSERT( nIndexInDataArray >= 0 &&
nIndexInDataArray < g_NewSettings.m_aApplicationData.GetSize() );
aIndexesToRemove.Add( (PVOID)nIndexInDataArray );
}
}
//
// Remove the app data structures from our array
//
nElementsToRemove = aIndexesToRemove.GetSize();
while( nElementsToRemove > 0 )
{
nElementsToRemove -= 1;
nIndexInDataArray = (INT_PTR)aIndexesToRemove.GetAt( nElementsToRemove );
ASSERT( nIndexInDataArray >= 0 &&
nIndexInDataArray < g_NewSettings.m_aApplicationData.GetSize() );
g_NewSettings.m_aApplicationData.DeleteAt( nIndexInDataArray );
for( nCrtElement = 0; nCrtElement < nElementsToRemove; nCrtElement += 1)
{
nCrtIndexToAdjust = (INT_PTR)aIndexesToRemove.GetAt( nCrtElement );
if( nCrtIndexToAdjust > nIndexInDataArray )
{
aIndexesToRemove.SetAt( nCrtElement,
(PVOID)( nCrtIndexToAdjust - 1 ) );
}
}
}
//
// Fill out the list again
//
m_AppList.DeleteAllItems();
FillTheList();
}