mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
638 lines
16 KiB
638 lines
16 KiB
//
|
|
// 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();
|
|
}
|