Source code of Windows XP (NT5)
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

  1. //
  2. // Application Verifier UI
  3. // Copyright (c) Microsoft Corporation, 2001
  4. //
  5. //
  6. //
  7. // module: SelApp.cpp
  8. // author: DMihai
  9. // created: 02/22/2001
  10. //
  11. // Description:
  12. //
  13. // "Select applications to be verified" wizard page class.
  14. //
  15. #include "stdafx.h"
  16. #include "appverif.h"
  17. #include "SelApp.h"
  18. #include "AVGlobal.h"
  19. #include "Setting.h"
  20. #include "AVUtil.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. //
  27. // Help IDs
  28. //
  29. static DWORD MyHelpIds[] =
  30. {
  31. 0, 0
  32. };
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CSelectAppPage property page
  35. IMPLEMENT_DYNCREATE(CSelectAppPage, CAppverifPage)
  36. CSelectAppPage::CSelectAppPage() : CAppverifPage(CSelectAppPage::IDD)
  37. {
  38. //{{AFX_DATA_INIT(CSelectAppPage)
  39. // NOTE: the ClassWizard will add member initialization here
  40. //}}AFX_DATA_INIT
  41. }
  42. CSelectAppPage::~CSelectAppPage()
  43. {
  44. }
  45. void CSelectAppPage::DoDataExchange(CDataExchange* pDX)
  46. {
  47. CAppverifPage::DoDataExchange(pDX);
  48. //{{AFX_DATA_MAP(CSelectAppPage)
  49. DDX_Control(pDX, IDC_SELECTAPPS_LIST, m_AppList);
  50. DDX_Control(pDX, IDC_SELECTAPPS_NEXTDESCR_STATIC, m_NextDescription);
  51. //}}AFX_DATA_MAP
  52. }
  53. BEGIN_MESSAGE_MAP(CSelectAppPage, CAppverifPage)
  54. //{{AFX_MSG_MAP(CSelectAppPage)
  55. ON_MESSAGE( WM_HELP, OnHelp )
  56. ON_WM_CONTEXTMENU()
  57. ON_BN_CLICKED(IDC_SELECTAPPS_ADD_BUTTON, OnAddButton)
  58. ON_BN_CLICKED(IDC_SELECTAPPS_REMOVE_BUTTON, OnRemoveButton)
  59. //}}AFX_MSG_MAP
  60. END_MESSAGE_MAP()
  61. /////////////////////////////////////////////////////////////////////////////
  62. ULONG CSelectAppPage::GetDialogId() const
  63. {
  64. return IDD_APPLICATION_PAGE;
  65. }
  66. /////////////////////////////////////////////////////////////////////////////
  67. VOID CSelectAppPage::SetupListHeader()
  68. {
  69. CString strTitle;
  70. CRect rectWnd;
  71. LVCOLUMN lvColumn;
  72. //
  73. // The list's rectangle
  74. //
  75. m_AppList.GetClientRect( &rectWnd );
  76. ZeroMemory( &lvColumn,
  77. sizeof( lvColumn ) );
  78. lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  79. lvColumn.fmt = LVCFMT_LEFT;
  80. //
  81. // Column 0
  82. //
  83. VERIFY( strTitle.LoadString( IDS_FILE_NAME ) );
  84. lvColumn.iSubItem = 0;
  85. lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
  86. lvColumn.cx = (int)( rectWnd.Width() * 0.17 );
  87. VERIFY( m_AppList.InsertColumn( 0, &lvColumn ) != -1 );
  88. strTitle.ReleaseBuffer();
  89. //
  90. // Column 1
  91. //
  92. VERIFY( strTitle.LoadString( IDS_FILE_VERSION ) );
  93. lvColumn.iSubItem = 1;
  94. lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
  95. lvColumn.cx = (int)( rectWnd.Width() * 0.15 );
  96. VERIFY( m_AppList.InsertColumn( 1, &lvColumn ) != -1 );
  97. strTitle.ReleaseBuffer();
  98. //
  99. // Column 2
  100. //
  101. VERIFY( strTitle.LoadString( IDS_COMPANY ) );
  102. lvColumn.iSubItem = 2;
  103. lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
  104. lvColumn.cx = (int)( rectWnd.Width() * 0.30 );
  105. VERIFY( m_AppList.InsertColumn( 2, &lvColumn ) != -1 );
  106. strTitle.ReleaseBuffer();
  107. //
  108. // Column 3
  109. //
  110. VERIFY( strTitle.LoadString( IDS_PRODUCT_NAME ) );
  111. lvColumn.iSubItem = 3;
  112. lvColumn.pszText = strTitle.GetBuffer( strTitle.GetLength() + 1 );
  113. lvColumn.cx = (int)( rectWnd.Width() * 0.38 );
  114. VERIFY( m_AppList.InsertColumn( 3, &lvColumn ) != -1 );
  115. strTitle.ReleaseBuffer();
  116. }
  117. /////////////////////////////////////////////////////////////////////////////
  118. VOID CSelectAppPage::SortTheList()
  119. {
  120. }
  121. /////////////////////////////////////////////////////////////////////////////
  122. INT CSelectAppPage::AddListItem( INT_PTR nIndexInDataArray,
  123. CApplicationData *pAppData )
  124. {
  125. INT nActualIndex;
  126. LVITEM lvItem;
  127. ASSERT_VALID( pAppData );
  128. nActualIndex = -1;
  129. ZeroMemory( &lvItem, sizeof( lvItem ) );
  130. //
  131. // LVITEM's member pszText is not a const pointer
  132. // so we need to GetBuffer here :-(
  133. //
  134. //
  135. // Sub-item 0 - file name
  136. //
  137. lvItem.pszText = pAppData->m_strExeFileName.GetBuffer(
  138. pAppData->m_strExeFileName.GetLength() + 1 );
  139. if( NULL == lvItem.pszText )
  140. {
  141. goto Done;
  142. }
  143. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  144. lvItem.lParam = nIndexInDataArray;
  145. lvItem.iItem = m_AppList.GetItemCount();
  146. nActualIndex = m_AppList.InsertItem( &lvItem );
  147. pAppData->m_strExeFileName.ReleaseBuffer();
  148. if( nActualIndex < 0 )
  149. {
  150. //
  151. // Could not add an item in the list - give up
  152. //
  153. goto Done;
  154. }
  155. //
  156. // Sub-item 1 - file version
  157. //
  158. lvItem.pszText = pAppData->m_strFileVersion.GetBuffer(
  159. pAppData->m_strFileVersion.GetLength() + 1 );
  160. if( NULL == lvItem.pszText )
  161. {
  162. goto Done;
  163. }
  164. lvItem.mask = LVIF_TEXT;
  165. lvItem.iItem = nActualIndex;
  166. lvItem.iSubItem = 1;
  167. VERIFY( m_AppList.SetItem( &lvItem ) );
  168. pAppData->m_strFileVersion.ReleaseBuffer();
  169. //
  170. // Sub-item 2 - provider
  171. //
  172. lvItem.pszText = pAppData->m_strCompanyName.GetBuffer(
  173. pAppData->m_strCompanyName.GetLength() + 1 );
  174. if( NULL == lvItem.pszText )
  175. {
  176. goto Done;
  177. }
  178. lvItem.mask = LVIF_TEXT;
  179. lvItem.iItem = nActualIndex;
  180. lvItem.iSubItem = 2;
  181. VERIFY( m_AppList.SetItem( &lvItem ) );
  182. pAppData->m_strCompanyName.ReleaseBuffer();
  183. //
  184. // Sub-item 3 - product name
  185. //
  186. lvItem.pszText = pAppData->m_strProductName.GetBuffer(
  187. pAppData->m_strProductName.GetLength() + 1 );
  188. if( NULL == lvItem.pszText )
  189. {
  190. goto Done;
  191. }
  192. lvItem.mask = LVIF_TEXT;
  193. lvItem.iItem = nActualIndex;
  194. lvItem.iSubItem = 3;
  195. VERIFY( m_AppList.SetItem( &lvItem ) );
  196. pAppData->m_strProductName.ReleaseBuffer();
  197. Done:
  198. //
  199. // All done
  200. //
  201. return nActualIndex;
  202. }
  203. /////////////////////////////////////////////////////////////////////////////
  204. VOID CSelectAppPage::FillTheList()
  205. {
  206. INT_PTR nVerifiedApps;
  207. INT_PTR nCrtVerifiedApp;
  208. CApplicationData *pAppData;
  209. nVerifiedApps = g_NewSettings.m_aApplicationData.GetSize();
  210. for( nCrtVerifiedApp = 0; nCrtVerifiedApp < nVerifiedApps; nCrtVerifiedApp +=1 )
  211. {
  212. pAppData = g_NewSettings.m_aApplicationData.GetAt( nCrtVerifiedApp );
  213. ASSERT_VALID( pAppData );
  214. AddListItem( nCrtVerifiedApp,
  215. pAppData );
  216. }
  217. }
  218. /////////////////////////////////////////////////////////////////////////////
  219. // CSelectAppPage message handlers
  220. /////////////////////////////////////////////////////////////
  221. LONG CSelectAppPage::OnHelp( WPARAM wParam, LPARAM lParam )
  222. {
  223. LONG lResult = 0;
  224. LPHELPINFO lpHelpInfo = (LPHELPINFO)lParam;
  225. ::WinHelp(
  226. (HWND) lpHelpInfo->hItemHandle,
  227. g_szAVHelpFile,
  228. HELP_WM_HELP,
  229. (DWORD_PTR) MyHelpIds );
  230. return lResult;
  231. }
  232. /////////////////////////////////////////////////////////////////////////////
  233. void CSelectAppPage::OnContextMenu(CWnd* pWnd, CPoint point)
  234. {
  235. ::WinHelp(
  236. pWnd->m_hWnd,
  237. g_szAVHelpFile,
  238. HELP_CONTEXTMENU,
  239. (DWORD_PTR) MyHelpIds );
  240. }
  241. /////////////////////////////////////////////////////////////////////////////
  242. BOOL CSelectAppPage::OnWizardFinish()
  243. {
  244. BOOL bExitTheApp;
  245. INT nResponse;
  246. ASSERT( AVSettingsTypeStandard == g_NewSettings.m_SettingsType );
  247. if( m_AppList.GetItemCount() > 0 )
  248. {
  249. //
  250. // Have at least one app selected to be verified
  251. //
  252. bExitTheApp = AVSaveNewSettings();
  253. }
  254. else
  255. {
  256. //
  257. // No apps in the list
  258. //
  259. nResponse = AVMesssageBoxFromResource( IDS_SELECT_AT_LEAST_ONE_APP,
  260. MB_YESNO | MB_ICONQUESTION );
  261. //
  262. // The user might choose to delete all settings here
  263. //
  264. bExitTheApp = ( nResponse == IDYES ) && AVSaveNewSettings();
  265. }
  266. return bExitTheApp;
  267. }
  268. /////////////////////////////////////////////////////////////////////////////
  269. BOOL CSelectAppPage::OnSetActive()
  270. {
  271. ASSERT_VALID( m_pParentSheet );
  272. ASSERT( AVSettingsTypeStandard == g_NewSettings.m_SettingsType );
  273. m_pParentSheet->SetWizardButtons( PSWIZB_BACK | PSWIZB_FINISH );
  274. //
  275. // Display the description of the next step
  276. //
  277. AVSetWindowText( m_NextDescription, IDS_SELAPP_FINISH_DESCR );
  278. return CAppverifPage::OnSetActive();
  279. }
  280. /////////////////////////////////////////////////////////////////////////////
  281. BOOL CSelectAppPage::OnInitDialog()
  282. {
  283. CAppverifPage::OnInitDialog();
  284. m_AppList.SetExtendedStyle(
  285. LVS_EX_FULLROWSELECT | m_AppList.GetExtendedStyle() );
  286. //
  287. // Setup our list and fill it out if we already have something in the app names array
  288. //
  289. SetupListHeader();
  290. FillTheList();
  291. return TRUE; // return TRUE unless you set the focus to a control
  292. // EXCEPTION: OCX Property Pages should return FALSE
  293. }
  294. /////////////////////////////////////////////////////////////////////////////
  295. // CSelectAppPage message handlers
  296. #define VRF_MAX_CHARS_FOR_OPEN 4096
  297. void CSelectAppPage::OnAddButton()
  298. {
  299. POSITION pos;
  300. DWORD dwOldMaxFileName = 0;
  301. DWORD dwErrorCode;
  302. INT nFileNameStartIndex;
  303. INT nNewListItemIndex;
  304. INT_PTR nResult;
  305. INT_PTR nNewAppDataIndex;
  306. CApplicationData *pNewAppData;
  307. TCHAR *szFilesBuffer = NULL;
  308. TCHAR *szOldFilesBuffer = NULL;
  309. CString strPathName;
  310. CString strFileName;
  311. CFileDialog fileDlg(
  312. TRUE, // open file
  313. _T( "exe" ), // default extension
  314. NULL, // no initial file name
  315. OFN_ALLOWMULTISELECT | // multiple selection
  316. OFN_HIDEREADONLY | // hide the "open read-only" checkbox
  317. OFN_NONETWORKBUTTON | // no network button
  318. OFN_NOTESTFILECREATE | // don't test for write protection, a full disk, etc.
  319. OFN_SHAREAWARE, // don't check the existance of file with OpenFile
  320. _T( "Executable Files (*.exe)|*.exe||" ) ); // only one filter
  321. //
  322. // Check the max length for the returned string
  323. //
  324. if( fileDlg.m_ofn.nMaxFile < VRF_MAX_CHARS_FOR_OPEN )
  325. {
  326. //
  327. // Allocate a new buffer for the file names
  328. //
  329. szFilesBuffer = new TCHAR[ VRF_MAX_CHARS_FOR_OPEN ];
  330. szFilesBuffer[ 0 ] = (TCHAR)0;
  331. if( szFilesBuffer != NULL )
  332. {
  333. //
  334. // Save the old buffer address and length
  335. //
  336. dwOldMaxFileName = fileDlg.m_ofn.nMaxFile;
  337. szOldFilesBuffer = fileDlg.m_ofn.lpstrFile;
  338. //
  339. // Set the new buffer address and length
  340. //
  341. fileDlg.m_ofn.lpstrFile = szFilesBuffer;
  342. fileDlg.m_ofn.nMaxFile = VRF_MAX_CHARS_FOR_OPEN;
  343. }
  344. }
  345. fileDlg.m_ofn.lpstrTitle = (LPCTSTR) g_strAppName;
  346. //
  347. // Show the file selection dialog
  348. //
  349. nResult = fileDlg.DoModal();
  350. switch( nResult )
  351. {
  352. case IDOK:
  353. break;
  354. case IDCANCEL:
  355. goto cleanup;
  356. default:
  357. dwErrorCode = CommDlgExtendedError();
  358. if( dwErrorCode == FNERR_BUFFERTOOSMALL )
  359. {
  360. AVErrorResourceFormat(
  361. IDS_TOO_MANY_FILES_SELECTED );
  362. }
  363. else
  364. {
  365. AVErrorResourceFormat(
  366. IDS_CANNOT_OPEN_FILES,
  367. dwErrorCode );
  368. }
  369. goto cleanup;
  370. }
  371. //
  372. // Parse all the selected files and try to enable them for verification
  373. //
  374. pos = fileDlg.GetStartPosition();
  375. while( pos != NULL )
  376. {
  377. //
  378. // Get the full path for the next file
  379. //
  380. strPathName = fileDlg.GetNextPathName( pos );
  381. //
  382. // Split only the file name, without the directory
  383. //
  384. nFileNameStartIndex = strPathName.ReverseFind( _T( '\\' ) );
  385. if( nFileNameStartIndex < 0 )
  386. {
  387. //
  388. // This shoudn't happen but you never know :-)
  389. //
  390. nFileNameStartIndex = 0;
  391. }
  392. else
  393. {
  394. //
  395. // Skip the backslash
  396. //
  397. nFileNameStartIndex += 1;
  398. }
  399. strFileName = strPathName.Right( strPathName.GetLength() - nFileNameStartIndex );
  400. //
  401. // Try to add this app to our global list
  402. //
  403. if( g_NewSettings.m_aApplicationData.IsFileNameInList( strFileName ) )
  404. {
  405. AVErrorResourceFormat( IDS_APP_IS_ALREADY_IN_LIST,
  406. (LPCTSTR) strFileName );
  407. }
  408. else
  409. {
  410. nNewAppDataIndex = g_NewSettings.m_aApplicationData.AddNewAppData( strFileName,
  411. strPathName,
  412. g_dwNewSettingBits );
  413. if( nNewAppDataIndex >= 0 )
  414. {
  415. //
  416. // Add a new item to our list corresponding to this app
  417. //
  418. pNewAppData = g_NewSettings.m_aApplicationData.GetAt( nNewAppDataIndex );
  419. ASSERT_VALID( pNewAppData );
  420. nNewListItemIndex = AddListItem( nNewAppDataIndex,
  421. pNewAppData );
  422. if( nNewListItemIndex >= 0 )
  423. {
  424. m_AppList.EnsureVisible( nNewListItemIndex, TRUE );
  425. }
  426. }
  427. }
  428. }
  429. cleanup:
  430. if( szFilesBuffer != NULL )
  431. {
  432. fileDlg.m_ofn.nMaxFile = dwOldMaxFileName;
  433. fileDlg.m_ofn.lpstrFile = szOldFilesBuffer;
  434. delete szFilesBuffer;
  435. }
  436. }
  437. /////////////////////////////////////////////////////////////////////////////
  438. void CSelectAppPage::OnRemoveButton()
  439. {
  440. int nItems;
  441. int nCrtItem;
  442. INT_PTR nIndexInDataArray;
  443. INT_PTR nElementsToRemove;
  444. INT_PTR nCrtElement;
  445. INT_PTR nCrtIndexToAdjust;
  446. CPtrArray aIndexesToRemove;
  447. //
  448. // Add the index of all the apps to remove from the
  449. // g_NewSettings.m_aApplicationData array in aIndexesToRemove.
  450. //
  451. nItems = m_AppList.GetItemCount();
  452. for( nCrtItem = 0; nCrtItem < nItems; nCrtItem++ )
  453. {
  454. if( m_AppList.GetItemState( nCrtItem, LVIS_SELECTED ) &
  455. LVIS_SELECTED )
  456. {
  457. nIndexInDataArray = (UINT)m_AppList.GetItemData( nCrtItem );
  458. ASSERT( nIndexInDataArray >= 0 &&
  459. nIndexInDataArray < g_NewSettings.m_aApplicationData.GetSize() );
  460. aIndexesToRemove.Add( (PVOID)nIndexInDataArray );
  461. }
  462. }
  463. //
  464. // Remove the app data structures from our array
  465. //
  466. nElementsToRemove = aIndexesToRemove.GetSize();
  467. while( nElementsToRemove > 0 )
  468. {
  469. nElementsToRemove -= 1;
  470. nIndexInDataArray = (INT_PTR)aIndexesToRemove.GetAt( nElementsToRemove );
  471. ASSERT( nIndexInDataArray >= 0 &&
  472. nIndexInDataArray < g_NewSettings.m_aApplicationData.GetSize() );
  473. g_NewSettings.m_aApplicationData.DeleteAt( nIndexInDataArray );
  474. for( nCrtElement = 0; nCrtElement < nElementsToRemove; nCrtElement += 1)
  475. {
  476. nCrtIndexToAdjust = (INT_PTR)aIndexesToRemove.GetAt( nCrtElement );
  477. if( nCrtIndexToAdjust > nIndexInDataArray )
  478. {
  479. aIndexesToRemove.SetAt( nCrtElement,
  480. (PVOID)( nCrtIndexToAdjust - 1 ) );
  481. }
  482. }
  483. }
  484. //
  485. // Fill out the list again
  486. //
  487. m_AppList.DeleteAllItems();
  488. FillTheList();
  489. }