Leaked source code of windows server 2003
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.

909 lines
28 KiB

  1. // MapWPge.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include <iadmw.h>
  5. #include "certmap.h"
  6. extern "C"
  7. {
  8. #include <wincrypt.h>
  9. #include <schannel.h>
  10. }
  11. #include "Iismap.hxx"
  12. #include "Iiscmr.hxx"
  13. #include "brwsdlg.h"
  14. #include "ListRow.h"
  15. #include "ChkLstCt.h"
  16. #include "MapWPge.h"
  17. #include "Ed11Maps.h"
  18. #include "EdWldRul.h"
  19. #include <iiscnfgp.h>
  20. #include "wrapmb.h"
  21. #include "WWzOne.h"
  22. #include "WWzTwo.h"
  23. #include "WWzThree.h"
  24. #include <lmcons.h>
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. #define COL_NUM_ENABLED 0
  31. #define COL_NUM_DESCRIPTION 1
  32. #define COL_NUM_NTACCOUNT 2
  33. //
  34. // valid only when accessing IIS5.1 or IIS5
  35. //
  36. #define MB_EXTEND_KEY "CertW"
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CMapWildcardsPge property page
  39. IMPLEMENT_DYNCREATE(CMapWildcardsPge, CPropertyPage)
  40. //---------------------------------------------------------------------------
  41. CMapWildcardsPge::CMapWildcardsPge() : CPropertyPage(CMapWildcardsPge::IDD),
  42. m_fDirty(FALSE)
  43. {
  44. //{{AFX_DATA_INIT(CMapWildcardsPge)
  45. m_bool_enable = FALSE;
  46. //}}AFX_DATA_INIT
  47. m_fIsIIS6 = TRUE;
  48. }
  49. //---------------------------------------------------------------------------
  50. CMapWildcardsPge::~CMapWildcardsPge()
  51. {
  52. }
  53. //---------------------------------------------------------------------------
  54. void CMapWildcardsPge::DoDataExchange(CDataExchange* pDX)
  55. {
  56. CPropertyPage::DoDataExchange(pDX);
  57. //{{AFX_DATA_MAP(CMapWildcardsPge)
  58. DDX_Control(pDX, IDC_LIST, m_clistctrl_list);
  59. DDX_Control(pDX, IDC_MOVE_UP, m_cbutton_up);
  60. DDX_Control(pDX, IDC_MOVE_DOWN, m_cbutton_down);
  61. DDX_Control(pDX, IDC_ADD, m_cbutton_add);
  62. DDX_Control(pDX, IDC_DELETE, m_cbutton_delete);
  63. DDX_Control(pDX, IDC_EDIT, m_cbutton_editrule);
  64. DDX_Check(pDX, IDC_ENABLE, m_bool_enable);
  65. //}}AFX_DATA_MAP
  66. }
  67. //---------------------------------------------------------------------------
  68. BEGIN_MESSAGE_MAP(CMapWildcardsPge, CPropertyPage)
  69. //{{AFX_MSG_MAP(CMapWildcardsPge)
  70. ON_BN_CLICKED(IDC_MOVE_DOWN, OnMoveDown)
  71. ON_BN_CLICKED(IDC_MOVE_UP, OnMoveUp)
  72. ON_BN_CLICKED(IDC_ADD, OnAdd)
  73. ON_BN_CLICKED(IDC_DELETE, OnDelete)
  74. ON_BN_CLICKED(IDC_EDIT, OnEdit)
  75. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnItemchangedList)
  76. ON_NOTIFY(NM_DBLCLK, IDC_LIST, OnDblclkList)
  77. ON_BN_CLICKED(IDC_ENABLE, OnEnable)
  78. //}}AFX_MSG_MAP
  79. ON_COMMAND(ID_HELP_FINDER, DoHelp)
  80. ON_COMMAND(ID_HELP, DoHelp)
  81. ON_COMMAND(ID_CONTEXT_HELP, DoHelp)
  82. ON_COMMAND(ID_DEFAULT_HELP, DoHelp)
  83. END_MESSAGE_MAP()
  84. //---------------------------------------------------------------------------
  85. void CMapWildcardsPge::DoHelp()
  86. {
  87. WinHelpDebug(HIDD_CERTMAP_MAIN_ADVANCED);
  88. WinHelp( HIDD_CERTMAP_MAIN_ADVANCED );
  89. }
  90. /////////////////////////////////////////////////////////////////////////////
  91. // initialization routines
  92. //---------------------------------------------------------------------------
  93. // FInitMapper is called by the routine instantiating this page. After the object
  94. // is first created is when it is called. It allows us to fail gracefully.
  95. BOOL CMapWildcardsPge::FInit(IMSAdminBase* pMB)
  96. {
  97. BOOL fAnswer = FALSE;
  98. PVOID pData = NULL;
  99. DWORD cbData = 0;
  100. BOOL f;
  101. m_pMB = pMB;
  102. // before messing with the metabase, prepare the strings we will need
  103. CString szObjectPath;
  104. // check if it's for older than iis6 version
  105. m_fIsIIS6 = TRUE;
  106. if (IsLegacyMetabase(pMB)){m_fIsIIS6 = FALSE;}
  107. if ( !m_fIsIIS6 )
  108. {
  109. szObjectPath = m_szMBPath + SZ_NAMESPACE_EXTENTION +
  110. _T('/') + MB_EXTEND_KEY;
  111. }
  112. else
  113. {
  114. szObjectPath = m_szMBPath;
  115. }
  116. // prepare the metabase wrapper
  117. CWrapMetaBase mbWrap;
  118. f = mbWrap.FInit(m_pMB);
  119. if ( !f ) return FALSE;
  120. // attempt to open the object we want to store into
  121. f = mbWrap.Open( szObjectPath, METADATA_PERMISSION_READ );
  122. // if that worked, load the data
  123. if ( f )
  124. {
  125. // first, get the size of the data that we are looking for
  126. pData = mbWrap.GetData( _T(""), MD_SERIAL_CERTW, IIS_MD_UT_SERVER, BINARY_METADATA, &cbData );
  127. // if we successfully got the data, unserialize it
  128. // WARNING: m_mapper.Unserialize changes the value of the pointer that is passed in. Pass
  129. // in a copy of the pointer
  130. PUCHAR pDataCopy = (PUCHAR)pData;
  131. if ( pData && (cbData > 0))
  132. fAnswer = m_mapper.Unserialize( (PUCHAR*)&pDataCopy, &cbData );
  133. // close the object
  134. f = mbWrap.Close();
  135. // cleanup
  136. if ( pData )
  137. mbWrap.FreeWrapData( pData );
  138. }
  139. // return the answer
  140. return fAnswer;
  141. }
  142. //---------------------------------------------------------------------------
  143. BOOL CMapWildcardsPge::OnInitDialog()
  144. {
  145. //call the parental oninitdialog
  146. BOOL f = CPropertyPage::OnInitDialog();
  147. // if the initinalization (sp?) succeeded, init the list and other items
  148. if ( f )
  149. {
  150. // init the contents of the list
  151. FInitRulesList();
  152. // Fill the mapping list with the stored items
  153. FillRulesList();
  154. // set the initial button states
  155. EnableDependantButtons();
  156. }
  157. // set the initial state of the enable button
  158. // get the globals object
  159. CCertGlobalRuleInfo* pGlob = m_mapper.GetGlobalRulesInfo();
  160. m_bool_enable = pGlob->GetRulesEnabled();
  161. // set any changes in the info into place
  162. UpdateData(FALSE);
  163. // return the answer
  164. return f;
  165. }
  166. //---------------------------------------------------------------------------
  167. BOOL CMapWildcardsPge::FInitRulesList()
  168. {
  169. CString sz;
  170. int i;
  171. // setup the friendly name column
  172. sz.Empty();
  173. i = m_clistctrl_list.InsertColumn( COL_NUM_ENABLED, sz, LVCFMT_LEFT, 20 );
  174. // setup the description column
  175. sz.LoadString( IDS_WILD_DESCRIPTION );
  176. i = m_clistctrl_list.InsertColumn( COL_NUM_DESCRIPTION, sz, LVCFMT_LEFT, 238 );
  177. // setup the account column
  178. sz.LoadString( IDS_WILD_ACCOUNT );
  179. i = m_clistctrl_list.InsertColumn( COL_NUM_NTACCOUNT, sz, LVCFMT_LEFT, 220 );
  180. return TRUE;
  181. }
  182. //---------------------------------------------------------------------------
  183. // fill in the rules. Get the order for the rules from the globals object. That
  184. // way there is no need to sort them later
  185. BOOL CMapWildcardsPge::FillRulesList()
  186. {
  187. // get the globals object
  188. CCertGlobalRuleInfo* pGlob = m_mapper.GetGlobalRulesInfo();
  189. // get the number of rules (actually its a number of rule order - but they are the same thing)
  190. DWORD cbRules = m_mapper.GetRuleCount();
  191. // get the pointer to the order array
  192. DWORD* pOrder = pGlob->GetRuleOrderArray();
  193. // for each item in the mapper object, add it to the list control
  194. for ( DWORD j = 0; j < cbRules; j++ )
  195. {
  196. CCertMapRule* pRule;
  197. DWORD iRule = pOrder[j];
  198. // get the mapping
  199. pRule = m_mapper.GetRule( iRule );
  200. // if that worked, add it to the list
  201. if ( pRule )
  202. {
  203. // add it to the list
  204. AddRuleToList( pRule, iRule, 0xffffffff );
  205. }
  206. }
  207. // it worked - so ok.
  208. return TRUE;
  209. }
  210. //---------------------------------------------------------------------------
  211. int CMapWildcardsPge::AddRuleToList( CCertMapRule* pRule, DWORD iRule, int iInsert )
  212. {
  213. CString sz;
  214. int i;
  215. if ( !pRule )
  216. return -1;
  217. // if the item to be inserted is to be the last, set it up
  218. if ( iInsert == 0xffffffff )
  219. iInsert = m_clistctrl_list.GetItemCount();
  220. // get the appropriate "enabled" string
  221. BOOL fEnabled = pRule->GetRuleEnabled();
  222. if ( fEnabled )
  223. sz.LoadString( IDS_ENABLED );
  224. else
  225. sz.Empty();
  226. // add the friendly name of the mapping
  227. // create the new entry in the list box. Do not sort on this entry - yet
  228. i = m_clistctrl_list.InsertItem( iInsert, sz );
  229. // add the friendly name of the rule
  230. sz = pRule->GetRuleName();
  231. // create the new entry in the list box. Do not sort on this entry - yet
  232. m_clistctrl_list.SetItemText( i, COL_NUM_DESCRIPTION, sz );
  233. // add the account name of the mapping
  234. if ( pRule->GetRuleDenyAccess() )
  235. sz.LoadString( IDS_DENYACCESS );
  236. else
  237. sz = pRule->GetRuleAccount();
  238. m_clistctrl_list.SetItemText( i, COL_NUM_NTACCOUNT, sz );
  239. // attach the mapper index to the item in the list - it may have a different
  240. // list index after the list has been sorted.
  241. m_clistctrl_list.SetItemData( i, iRule );
  242. // return whether or not the insertion succeeded
  243. return i;
  244. }
  245. //---------------------------------------------------------------------------
  246. // Note: supposedly, the order of the items in the list and the odrder
  247. // of the items in the globals object should be the same
  248. void CMapWildcardsPge::UpdateRuleInDispList( DWORD iList, CCertMapRule* pRule )
  249. {
  250. CString sz;
  251. // get the appropriate "enabled" string
  252. BOOL fEnabled = pRule->GetRuleEnabled();
  253. if ( fEnabled )
  254. sz.LoadString( IDS_ENABLED );
  255. else
  256. sz.Empty();
  257. // update the "Enabled" indicator
  258. m_clistctrl_list.SetItemText( iList, COL_NUM_ENABLED, sz );
  259. // update the mapping name
  260. sz = pRule->GetRuleName();
  261. m_clistctrl_list.SetItemText( iList, COL_NUM_DESCRIPTION, sz );
  262. // update the account name
  263. if ( pRule->GetRuleDenyAccess() )
  264. sz.LoadString( IDS_DENYACCESS );
  265. else
  266. sz = pRule->GetRuleAccount();
  267. m_clistctrl_list.SetItemText( iList, COL_NUM_NTACCOUNT, sz );
  268. }
  269. //---------------------------------------------------------------------------
  270. // editing a wildcard rule is rather complex, thus I am seperating that code
  271. // out into that for the dialog itself. All we do is pass in the rule pointer
  272. // and let it go at that.
  273. BOOL CMapWildcardsPge::EditOneRule( CCertMapRule* pRule, BOOL fAsWizard )
  274. {
  275. // edit the item using a tabbed dialog / wizard
  276. CPropertySheet propSheet;
  277. CWildWizOne wwOne;
  278. CWildWizTwo wwTwo;
  279. CWildWizThree wwThree;
  280. // set the params
  281. wwOne.m_pMB = m_pMB;
  282. // fill in the data for the pages
  283. wwOne.m_pRule = pRule;
  284. wwOne.m_szMBPath = m_szMBPath;
  285. wwOne.m_fIsWizard = fAsWizard;
  286. wwOne.m_pPropSheet = &propSheet;
  287. wwTwo.m_pRule = pRule;
  288. wwTwo.m_szMBPath = m_szMBPath;
  289. wwTwo.m_fIsWizard = fAsWizard;
  290. wwTwo.m_pPropSheet = &propSheet;
  291. wwThree.m_pRule = pRule;
  292. wwThree.m_szMBPath = m_szMBPath;
  293. wwThree.m_fIsWizard = fAsWizard;
  294. wwThree.m_pPropSheet = &propSheet;
  295. // add the pages
  296. propSheet.AddPage( &wwOne );
  297. propSheet.AddPage( &wwTwo );
  298. propSheet.AddPage( &wwThree );
  299. // turn it into a wizard if necessary
  300. if ( fAsWizard )
  301. propSheet.SetWizardMode();
  302. // set the title of the wizard/tabbed dialog thing
  303. CString szTitle;
  304. szTitle.LoadString( IDS_WILDWIZ_TITLE );
  305. propSheet.SetTitle( szTitle );
  306. // turn on help
  307. propSheet.m_psh.dwFlags |= PSH_HASHELP;
  308. wwOne.m_psp.dwFlags |= PSP_HASHELP;
  309. wwTwo.m_psp.dwFlags |= PSP_HASHELP;
  310. wwThree.m_psp.dwFlags |= PSP_HASHELP;
  311. // run the wizard and return if it ended with IDOK
  312. INT_PTR id = propSheet.DoModal();
  313. return ( (id == IDOK) || (id == ID_WIZFINISH) );
  314. /*
  315. CEditWildcardRule ruleDlg;
  316. // prepare
  317. ruleDlg.m_pRule = pRule;
  318. ruleDlg.m_szMBPath = m_szMBPath;
  319. // run the dialog and return if it ended with IDOK
  320. return (ruleDlg.DoModal() == IDOK);
  321. */
  322. }
  323. //---------------------------------------------------------------------------
  324. // Yeah! the CEdit11Mappings works equally well for multiple rules! - just
  325. // some modifications in this routine!
  326. BOOL CMapWildcardsPge::EditMultipleRules()
  327. {
  328. CEdit11Mappings mapdlg;
  329. CCertMapRule* pRule;
  330. BOOL fSetInitialState = FALSE;
  331. BOOL fEnable;
  332. // scan the list of seleted items for the proper initial enable button state
  333. // loop through the selected items, setting each one's mapping
  334. int iList = -1;
  335. while( (iList = m_clistctrl_list.GetNextItem( iList, LVNI_SELECTED )) >= 0 )
  336. {
  337. // get the mapper index for the item
  338. // IA64 - this is OK to cast to DWORD as it is just an index
  339. DWORD iMapper = (DWORD)m_clistctrl_list.GetItemData( iList );
  340. // get the mapping item for updating purposes
  341. pRule = m_mapper.GetRule( iMapper );
  342. if ( !pRule )
  343. {
  344. AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
  345. break;
  346. }
  347. // get the enable state of the mapping
  348. fEnable = pRule->GetRuleEnabled();
  349. // if this is the first time, just set the initial state
  350. if ( !fSetInitialState )
  351. {
  352. mapdlg.m_int_enable = fEnable;
  353. fSetInitialState = TRUE;
  354. }
  355. else
  356. {
  357. // if it is different, then go indeterminate and break
  358. if ( fEnable != mapdlg.m_int_enable )
  359. {
  360. mapdlg.m_int_enable = 2;
  361. break;
  362. }
  363. }
  364. }
  365. //
  366. // ANSI/UNICODE conversion - RonaldM
  367. //
  368. USES_CONVERSION;
  369. // run the mapping dialog
  370. if ( mapdlg.DoModal() == IDOK )
  371. {
  372. // loop through the selected items, setting each one's mapping
  373. int iList = -1;
  374. while( (iList = m_clistctrl_list.GetNextItem( iList, LVNI_SELECTED )) >= 0 )
  375. {
  376. // get the mapper index for the item
  377. // IA64 - this is OK to cast to DWORD as it is just an index
  378. DWORD iMapper = (DWORD)m_clistctrl_list.GetItemData( iList );
  379. // get the mapping item for updating purposes
  380. pRule = m_mapper.GetRule( iMapper );
  381. if ( !pRule )
  382. {
  383. AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
  384. break;
  385. }
  386. // set the enable flag if requested
  387. switch ( mapdlg.m_int_enable )
  388. {
  389. case 0: // disable
  390. pRule->SetRuleEnabled( FALSE );
  391. break;
  392. case 1: // enable
  393. pRule->SetRuleEnabled( TRUE );
  394. break;
  395. }
  396. // set the NT account field of the mapping object
  397. pRule->SetRuleAccount( T2A ((LPTSTR)(LPCTSTR)mapdlg.m_sz_accountname) );
  398. // update it in the list control too
  399. UpdateRuleInDispList( iList, pRule );
  400. }
  401. // activate the apply button
  402. SetModified();
  403. m_fDirty = TRUE;
  404. // return true because the user said "OK"
  405. return TRUE;
  406. }
  407. // return FALSE because the user did not say "OK"
  408. return FALSE;
  409. }
  410. //---------------------------------------------------------------------------
  411. void CMapWildcardsPge::EnableDependantButtons()
  412. {
  413. // the whole purpose of this routine is to gray or activate
  414. // the edit and delete buttons depending on whether or not anything
  415. // is selected. So start by getting the selection count
  416. UINT cItemsSel = m_clistctrl_list.GetSelectedCount();
  417. // if there is only one item selected, then possibly activate the up/down buttons
  418. if ( cItemsSel == 1 )
  419. {
  420. m_cbutton_up.EnableWindow( TRUE );
  421. m_cbutton_down.EnableWindow( TRUE );
  422. }
  423. else
  424. {
  425. m_cbutton_up.EnableWindow( FALSE );
  426. m_cbutton_down.EnableWindow( FALSE );
  427. }
  428. // now the more general case of multiple selections
  429. if ( cItemsSel > 0 )
  430. {
  431. // there are items selected
  432. m_cbutton_editrule.EnableWindow( TRUE );
  433. m_cbutton_delete.EnableWindow( TRUE );
  434. }
  435. else
  436. {
  437. // nope. Nothing selected
  438. m_cbutton_editrule.EnableWindow( FALSE );
  439. m_cbutton_delete.EnableWindow( FALSE );
  440. }
  441. // always enable the add button
  442. m_cbutton_add.EnableWindow( TRUE );
  443. }
  444. /////////////////////////////////////////////////////////////////////////////
  445. // CMapWildcardsPge message handlers
  446. //---------------------------------------------------------------------------
  447. BOOL CMapWildcardsPge::OnApply()
  448. {
  449. BOOL f;
  450. CStoreXBF xbf;
  451. METADATA_HANDLE hm;
  452. // if no changes have been made, then don't do anything
  453. if ( !m_fDirty )
  454. return TRUE;
  455. UpdateData( TRUE );
  456. CWaitCursor wait;
  457. // set the current value of enable into place
  458. // get the globals object
  459. CCertGlobalRuleInfo* pGlob = m_mapper.GetGlobalRulesInfo();
  460. pGlob->SetRulesEnabled( m_bool_enable );
  461. // serialize the reference to the mapper itself
  462. f = m_mapper.Serialize( &xbf );
  463. // before messing with the metabase, prepare the strings we will need
  464. CString szBasePath;
  465. CString szRelativePath;
  466. CString szObjectPath;
  467. if( !m_fIsIIS6 )
  468. {
  469. szBasePath = m_szMBPath;
  470. szRelativePath = MB_EXTEND_KEY;
  471. szObjectPath = m_szMBPath + _T('/') + szRelativePath;
  472. }
  473. else
  474. {
  475. //
  476. // On IIS6 and higher the CertW mapping info is saved
  477. // directly under the site node
  478. //
  479. szBasePath = m_szMBPath;
  480. szRelativePath = "";
  481. szObjectPath = m_szMBPath;
  482. }
  483. // prepare the metabase wrapper
  484. CWrapMetaBase mbWrap;
  485. f = mbWrap.FInit(m_pMB);
  486. // attempt to open the object we want to store into
  487. f = mbWrap.Open( szObjectPath, METADATA_PERMISSION_WRITE );
  488. // if that did not work, we need to add the object
  489. if ( !f )
  490. {
  491. // if szRelativePath is empty then fail right away
  492. // because there is no new node to be added
  493. if ( szRelativePath.IsEmpty() )
  494. {
  495. if ( !f )
  496. {
  497. AfxMessageBox(IDS_ERR_ACCESS_MAPPING);
  498. return FALSE;
  499. }
  500. }
  501. // need a slash after the namespace extention now
  502. szBasePath += _T('/');
  503. // open the base object
  504. f = mbWrap.Open( szBasePath, METADATA_PERMISSION_WRITE );
  505. if ( !f )
  506. {
  507. AfxMessageBox(IDS_ERR_ACCESS_MAPPING);
  508. return FALSE;
  509. }
  510. // add the object we want
  511. f = mbWrap.AddObject( szRelativePath );
  512. if ( !f )
  513. {
  514. AfxMessageBox(IDS_ERR_ACCESS_MAPPING);
  515. mbWrap.Close();
  516. return FALSE;
  517. }
  518. // close the base object
  519. f = mbWrap.Close();
  520. // attempt to open the object we want to store into
  521. f = mbWrap.Open( szObjectPath, METADATA_PERMISSION_WRITE );
  522. }
  523. // set the data into place in the object - If we were able to open it
  524. if ( f )
  525. {
  526. mbWrap.SetData( _T(""), MD_SERIAL_CERTW, IIS_MD_UT_SERVER, BINARY_METADATA, xbf.GetBuff(), xbf.GetUsed(), METADATA_SECURE );
  527. }
  528. // close the object
  529. f = mbWrap.Close();
  530. // save the changes to the metabase
  531. f = mbWrap.Save();
  532. // tell the persistence object to tuck away the reference so that we may find it later
  533. // f = m_persist.FSave( xbf.GetBuff(), xbf.GetUsed() );
  534. // deactivate the apply button
  535. SetModified( FALSE );
  536. m_fDirty = FALSE;
  537. // return f;
  538. return TRUE;
  539. }
  540. //---------------------------------------------------------------------------
  541. void CMapWildcardsPge::OnMove( int delta )
  542. {
  543. int iList;
  544. ASSERT( delta != 0 );
  545. // make sure there is only one item selected
  546. ASSERT( m_clistctrl_list.GetSelectedCount() == 1 );
  547. // Get the list index of the item in question.
  548. // this is also the index into the rule order array
  549. iList = m_clistctrl_list.GetNextItem( -1, LVNI_SELECTED );
  550. // get the globals object
  551. CCertGlobalRuleInfo* pGlob = m_mapper.GetGlobalRulesInfo();
  552. // get the number of rules (actually its a number of rule order - but they are the same thing)
  553. int cbRules = pGlob->GetRuleOrderCount();
  554. // test against the edge conditions
  555. if ( ((iList == 0) && (delta < 0)) | ((iList == (cbRules - 1)) && (delta > 0)) )
  556. return;
  557. // get the pointer to the order array
  558. DWORD * pOrder = pGlob->GetRuleOrderArray();
  559. // calculate the new position in the array
  560. int iNewPosition = iList + delta;
  561. // store away the mapper's iIndex (not the position) of the item
  562. UINT iIndex = pOrder[iList];
  563. // swap the positions
  564. DWORD itemp = pOrder[iNewPosition];
  565. pOrder[iNewPosition] = pOrder[iList];
  566. pOrder[iList] = itemp;
  567. ASSERT( pOrder[iNewPosition] == iIndex );
  568. // unfortunately, we can't just do that with the display list. We have to remove the
  569. // the item, then re-insert it. Its a flaw in the CListCtrl object. Arg.
  570. // we have to get the item too
  571. CCertMapRule* pRule = m_mapper.GetRule( iIndex );
  572. // delete the item from the display list
  573. m_clistctrl_list.DeleteItem( iList );
  574. // re-insert it
  575. int iNew = AddRuleToList( pRule, iIndex, iNewPosition );
  576. // make sure it is visible in the list
  577. m_clistctrl_list.EnsureVisible( iNew, FALSE );
  578. // finally, because its been removed and re-inserted, we need to
  579. // re-select it as well - CListCtrl is such a pain at this
  580. LV_ITEM lv;
  581. ZeroMemory( &lv, sizeof(lv) );
  582. lv.mask = LVIF_STATE;
  583. lv.iItem = iNew;
  584. lv.state = LVIS_SELECTED;
  585. lv.stateMask = LVIS_SELECTED;
  586. m_clistctrl_list.SetItem( &lv );
  587. // activate the apply button
  588. SetModified();
  589. m_fDirty = TRUE;
  590. }
  591. //---------------------------------------------------------------------------
  592. void CMapWildcardsPge::OnMoveDown()
  593. {
  594. OnMove( 1 );
  595. }
  596. //---------------------------------------------------------------------------
  597. void CMapWildcardsPge::OnMoveUp()
  598. {
  599. OnMove( -1 );
  600. }
  601. //---------------------------------------------------------------------------
  602. void CMapWildcardsPge::OnAdd()
  603. {
  604. CHAR sz[256];
  605. // create the new rule
  606. CCertMapRule * pNewRule = new CCertMapRule();
  607. if (pNewRule == NULL)
  608. return;
  609. // give the new rule some defaults
  610. LoadStringA(::AfxGetInstanceHandle(), IDS_DEFAULT_RULE, sz, 255 );
  611. pNewRule->SetRuleName( sz );
  612. pNewRule->SetRuleEnabled( TRUE );
  613. // Edit the rule. If it fails, remove it from the list
  614. if ( !EditOneRule( pNewRule, TRUE ) )
  615. {
  616. // kill the rule and return
  617. delete pNewRule;
  618. return;
  619. }
  620. // make a new mapper & get its index
  621. DWORD iNewRule = m_mapper.AddRule( pNewRule );
  622. // add the rule to the end of the display list. - It is added to the
  623. // end of the rule list by default
  624. AddRuleToList( pNewRule, iNewRule );
  625. // make sure it is visible in the list
  626. m_clistctrl_list.EnsureVisible( iNewRule, FALSE );
  627. // activate the apply button
  628. SetModified();
  629. m_fDirty = TRUE;
  630. }
  631. //---------------------------------------------------------------------------
  632. void CMapWildcardsPge::OnDelete()
  633. {
  634. // ask the user to confirm this decision
  635. if ( AfxMessageBox(IDS_CONFIRM_DELETE, MB_OKCANCEL) != IDOK )
  636. return;
  637. CWaitCursor wait;
  638. // loop through the selected items, setting each one's mapping
  639. int iList = -1;
  640. while( (iList = m_clistctrl_list.GetNextItem( -1, LVNI_SELECTED )) >= 0 )
  641. {
  642. // get the mapper index for the item
  643. // IA64 - this is OK to cast to DWORD as it is just an index
  644. DWORD iMapper = (DWORD)m_clistctrl_list.GetItemData( iList );
  645. // delete the mapping from the mapper
  646. m_mapper.DeleteRule( iMapper );
  647. // delete the entry from the list box
  648. m_clistctrl_list.DeleteItem( iList );
  649. // because the index in the mapper for all the items below this
  650. // one changes when it is deleted, we must go and fix them all.
  651. DWORD numItems = m_clistctrl_list.GetItemCount();
  652. for ( DWORD iFix = iList; iFix < numItems; iFix++ )
  653. {
  654. // get the mapper index for the item to be fixed
  655. // IA64 - this is OK to cast to DWORD as it is just an index
  656. iMapper = (DWORD)m_clistctrl_list.GetItemData( iFix );
  657. // decrement it to reflect the change
  658. iMapper--;
  659. // put it back.
  660. m_clistctrl_list.SetItemData( iFix, iMapper );
  661. }
  662. }
  663. // activate the apply button
  664. SetModified();
  665. m_fDirty = TRUE;
  666. }
  667. //---------------------------------------------------------------------------
  668. void CMapWildcardsPge::OnEdit()
  669. {
  670. int iList;
  671. DWORD iRule;
  672. CCertMapRule* pUpdateRule;
  673. // what happens here depends on if just one mapping is selected, or many
  674. switch( m_clistctrl_list.GetSelectedCount() )
  675. {
  676. case 0: // do nothing - should not get here because button grays out
  677. ASSERT( FALSE );
  678. break;
  679. case 1: // get the mapping for update and run single edit dialog
  680. // get index of the selected list item
  681. iList = m_clistctrl_list.GetNextItem( -1, LVNI_SELECTED );
  682. ASSERT( iList >= 0 );
  683. // get the mapper index for the item
  684. // IA64 - this is OK to cast to DWORD as it is just an index
  685. iRule = (DWORD)m_clistctrl_list.GetItemData( iList );
  686. // get the mapping item for updating purposes
  687. pUpdateRule = m_mapper.GetRule( iRule );
  688. if ( !pUpdateRule )
  689. {
  690. AfxMessageBox( IDS_ERR_ACCESS_MAPPING );
  691. break;
  692. }
  693. // edit the mapping, update it if successful, delete if not
  694. if ( EditOneRule(pUpdateRule) )
  695. {
  696. UpdateRuleInDispList( iList, pUpdateRule );
  697. // activate the apply button
  698. SetModified();
  699. m_fDirty = TRUE;
  700. }
  701. break;
  702. default: // run the multi edit dialog
  703. EditMultipleRules();
  704. break;
  705. }
  706. }
  707. //---------------------------------------------------------------------------
  708. void CMapWildcardsPge::OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult)
  709. {
  710. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  711. *pResult = 0;
  712. // enable the correct items
  713. EnableDependantButtons();
  714. }
  715. //---------------------------------------------------------------------------
  716. void CMapWildcardsPge::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult)
  717. {
  718. *pResult = 0;
  719. // if something in the list was double clicked, edit it
  720. if ( m_clistctrl_list.GetSelectedCount() > 0 )
  721. OnEdit();
  722. }
  723. //---------------------------------------------------------------------------
  724. void CMapWildcardsPge::OnEnable()
  725. {
  726. // activate the apply button
  727. SetModified();
  728. m_fDirty = TRUE;
  729. }