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.

1231 lines
21 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. mmmdlg.cpp
  5. Abstract:
  6. Multi-multi-multi dialog editor
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "w3scfg.h"
  18. #include "mmmdlg.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. //
  25. // Registry key name for this dialog
  26. //
  27. const TCHAR g_szRegKeyIP[] = _T("MMMIpBindings");
  28. const TCHAR g_szRegKeySSL[] = _T("MMMSSLBindings");
  29. //
  30. // IP Bindings Listbox Column Definitions
  31. //
  32. static const ODL_COLUMN_DEF g_aIPColumns[] =
  33. {
  34. // ===============================================
  35. // Weight Label
  36. // ===============================================
  37. { 6, IDS_MMM_IP_ADDRESS, },
  38. { 3, IDS_MMM_TCP_PORT, },
  39. { 10, IDS_MMM_DOMAIN_NAME, },
  40. };
  41. //
  42. // SSL Bindings Listbox Column Definitions
  43. //
  44. static const ODL_COLUMN_DEF g_aSSLColumns[] =
  45. {
  46. // ===============================================
  47. // Weight Label
  48. // ===============================================
  49. { 2, IDS_MMM_IP_ADDRESS, },
  50. { 1, IDS_MMM_SSL_PORT, },
  51. };
  52. #define NUM_COLUMNS(cols) (sizeof(cols) / sizeof(cols[0]))
  53. IMPLEMENT_DYNAMIC(CMMMListBox, CRMCListBox);
  54. //
  55. // Bitmap indices
  56. //
  57. enum
  58. {
  59. BMPID_BINDING,
  60. //
  61. // Don't move this one
  62. //
  63. BMPID_TOTAL
  64. };
  65. const int CMMMListBox::nBitmaps = BMPID_TOTAL;
  66. CMMMListBox::CMMMListBox(
  67. IN LPCTSTR lpszRegKey,
  68. IN int cColumns,
  69. IN const ODL_COLUMN_DEF * pColumns
  70. )
  71. /*++
  72. Routine Description:
  73. Constructor
  74. Arguments:
  75. None
  76. Return Value:
  77. N/A
  78. --*/
  79. : CHeaderListBox(HLS_STRETCH, lpszRegKey),
  80. m_cColumns(cColumns),
  81. m_pColumns(pColumns)
  82. {
  83. VERIFY(m_strDefaultIP.LoadString(IDS_DEFAULT));
  84. VERIFY(m_strNoPort.LoadString(IDS_MMM_NA));
  85. }
  86. void
  87. CMMMListBox::DrawItemEx(
  88. IN CRMCListBoxDrawStruct & ds
  89. )
  90. /*++
  91. Routine Description:
  92. Draw item in the listbox
  93. Arguments:
  94. CRMCListBoxDrawStruct & ds : Draw item structure
  95. Return Value:
  96. None
  97. --*/
  98. {
  99. CString & strBinding = *(CString *)ds.m_ItemData;
  100. TRACEEOLID(strBinding);
  101. UINT nPort;
  102. LPCTSTR lp;
  103. CString strHostHeader;
  104. CString strPort;
  105. CString strIP;
  106. CIPAddress iaIpAddress;
  107. CInstanceProps::CrackBinding(
  108. strBinding,
  109. iaIpAddress,
  110. nPort,
  111. strHostHeader
  112. );
  113. //
  114. // Display Granted/Denied with appropriate bitmap
  115. //
  116. DrawBitmap(ds, 0, BMPID_BINDING);
  117. if (iaIpAddress.IsZeroValue())
  118. {
  119. lp = m_strDefaultIP;
  120. }
  121. else
  122. {
  123. lp = iaIpAddress.QueryIPAddress(strIP);
  124. }
  125. ColumnText(ds, 0, TRUE, lp);
  126. if (nPort > 0)
  127. {
  128. strPort.Format(_T("%u"), nPort);
  129. lp = strPort;
  130. }
  131. else
  132. {
  133. lp = m_strNoPort;
  134. }
  135. ColumnText(ds, 1, FALSE, lp);
  136. ColumnText(ds, 2, FALSE, strHostHeader);
  137. }
  138. /* virtual */
  139. BOOL
  140. CMMMListBox::Initialize()
  141. /*++
  142. Routine Description:
  143. Initialize the listbox. Insert the columns as requested, and lay
  144. them out appropriately
  145. Arguments:
  146. None
  147. Return Value:
  148. TRUE for succesful initialisation, FALSE otherwise
  149. --*/
  150. {
  151. if (!CHeaderListBox::Initialize())
  152. {
  153. return FALSE;
  154. }
  155. //
  156. // Build all columns
  157. //
  158. for (int nCol = 0; nCol < m_cColumns; ++nCol)
  159. {
  160. InsertColumn(nCol, m_pColumns[nCol].nWeight, m_pColumns[nCol].nLabelID);
  161. }
  162. //
  163. // Try to set the widths from the stored registry value,
  164. // otherwise distribute according to column weights specified
  165. //
  166. if (!SetWidthsFromReg())
  167. {
  168. DistributeColumns();
  169. }
  170. return TRUE;
  171. }
  172. void AFXAPI
  173. DDXV_UINT(
  174. IN CDataExchange * pDX,
  175. IN UINT nID,
  176. IN OUT UINT & uValue,
  177. IN UINT uMin,
  178. IN UINT uMax,
  179. IN UINT nEmptyErrorMsg OPTIONAL
  180. )
  181. /*++
  182. Routine Description:
  183. DDX/DDV Function that uses a space to denote a 0 value
  184. Arguments:
  185. CDataExchange * pDX : Data exchange object
  186. UINT nID : Resource ID
  187. OUT UINT & uValue : Value
  188. UINT uMin : Minimum value
  189. UINT uMax : Maximum value
  190. UINT nEmptyErrorMsg : Error message ID for empty unit, or 0 if empty OK
  191. Return Value:
  192. None.
  193. --*/
  194. {
  195. ASSERT(uMin <= uMax);
  196. CWnd * pWnd = CWnd::FromHandle(pDX->PrepareEditCtrl(nID));
  197. ASSERT(pWnd != NULL);
  198. if (pDX->m_bSaveAndValidate)
  199. {
  200. if (pWnd->GetWindowTextLength() > 0)
  201. {
  202. DDX_Text(pDX, nID, uValue);
  203. DDV_MinMaxUInt(pDX, uValue, uMin, uMax);
  204. }
  205. else
  206. {
  207. uValue = 0;
  208. if (nEmptyErrorMsg)
  209. {
  210. ::AfxMessageBox(nEmptyErrorMsg);
  211. pDX->Fail();
  212. }
  213. }
  214. }
  215. else
  216. {
  217. if (uValue != 0)
  218. {
  219. DDX_Text(pDX, nID, uValue);
  220. }
  221. else
  222. {
  223. pWnd->SetWindowText(_T(""));
  224. }
  225. }
  226. }
  227. BOOL
  228. IsBindingUnique(
  229. IN CString & strBinding,
  230. IN CStringList & strlBindings,
  231. IN int iCurrent OPTIONAL
  232. )
  233. /*++
  234. Routine Description:
  235. Helper function to determine if a binding is unique.
  236. Arguments:
  237. CString & strBinding : Binding string
  238. CStringList & strlBindings : List of bindings
  239. int iCurrent : Index of "current" item.
  240. Not used for uniqueness checking.
  241. Return Value:
  242. TRUE if the binding is unique, FALSE otherwise.
  243. --*/
  244. {
  245. int iItem = 0;
  246. for(POSITION pos = strlBindings.GetHeadPosition(); pos != NULL; /**/ )
  247. {
  248. CString & str = strlBindings.GetNext(pos);
  249. if (iItem != iCurrent && &str != &strBinding && str == strBinding)
  250. {
  251. //
  252. // Not unique!
  253. //
  254. return FALSE;
  255. }
  256. ++iItem;
  257. }
  258. //
  259. // Unique
  260. //
  261. return TRUE;
  262. }
  263. //
  264. // Multi-multi-multi editing dialog
  265. //
  266. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  267. CMMMEditDlg::CMMMEditDlg(
  268. IN CString & strServerName,
  269. IN CStringList & strlBindings,
  270. IN CStringList & strlOtherBindings,
  271. IN OUT CString & entry,
  272. IN BOOL fIPBinding,
  273. IN CWnd * pParent OPTIONAL
  274. )
  275. /*++
  276. Routine Description:
  277. Constructor
  278. Arguments:
  279. CString & strServerName : Server name
  280. CStringList & strlBindings : bindings
  281. CStringList & strlOtherBindings : "other" bindings list
  282. CString & entry : Entry being edited
  283. BOOL fIPBinding : TRUE for IP, FALSE for SSL
  284. CWnd * pParent : Optional parent window
  285. Return Value:
  286. N/A
  287. --*/
  288. : CDialog(CMMMEditDlg::IDD, pParent),
  289. m_strServerName(strServerName),
  290. m_strlBindings(strlBindings),
  291. m_strlOtherBindings(strlOtherBindings),
  292. m_entry(entry),
  293. m_fIPBinding(fIPBinding),
  294. m_nIpAddressSel(-1)
  295. {
  296. #if 0 // Keep class wizard happy
  297. //{{AFX_DATA_INIT(CMMMEditDlg)
  298. m_nIpAddressSel = -1;
  299. //}}AFX_DATA_INIT
  300. #endif // 0
  301. CInstanceProps::CrackBinding(
  302. m_entry,
  303. m_iaIpAddress,
  304. m_nPort,
  305. m_strDomainName
  306. );
  307. }
  308. void
  309. CMMMEditDlg::DoDataExchange(
  310. IN CDataExchange * pDX
  311. )
  312. /*++
  313. Routine Description:
  314. Initialise/Store control data
  315. Arguments:
  316. CDataExchange * pDX - DDX/DDV control structure
  317. Return Value:
  318. None
  319. --*/
  320. {
  321. CDialog::DoDataExchange(pDX);
  322. //{{AFX_DATA_MAP(CMMMEditDlg)
  323. DDX_Text(pDX, IDC_EDIT_DOMAIN_NAME, m_strDomainName);
  324. DDV_MaxChars(pDX, m_strDomainName, MAX_PATH);
  325. DDX_Control(pDX, IDC_COMBO_IP_ADDRESSES, m_combo_IpAddresses);
  326. DDX_Control(pDX, IDC_STATIC_PORT, m_static_Port);
  327. //}}AFX_DATA_MAP
  328. DDXV_UINT(pDX, IDC_EDIT_PORT, m_nPort, 1, 65535);
  329. DDX_CBIndex(pDX, IDC_COMBO_IP_ADDRESSES, m_nIpAddressSel);
  330. if (pDX->m_bSaveAndValidate && !FetchIpAddressFromCombo(
  331. m_combo_IpAddresses,
  332. m_oblIpAddresses,
  333. m_iaIpAddress
  334. ))
  335. {
  336. pDX->Fail();
  337. }
  338. }
  339. //
  340. // Message Map
  341. //
  342. BEGIN_MESSAGE_MAP(CMMMEditDlg, CDialog)
  343. //{{AFX_MSG_MAP(CMMMEditDlg)
  344. //}}AFX_MSG_MAP
  345. END_MESSAGE_MAP()
  346. //
  347. // Message Handlers
  348. //
  349. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  350. BOOL
  351. CMMMEditDlg::OnInitDialog()
  352. /*++
  353. Routine Description:
  354. WM_INITDIALOG handler. Initialize the dialog.
  355. Arguments:
  356. None.
  357. Return Value:
  358. TRUE if focus is to be set automatically, FALSE if the focus
  359. is already set.
  360. --*/
  361. {
  362. CDialog::OnInitDialog();
  363. BeginWaitCursor();
  364. PopulateComboWithKnownIpAddresses(
  365. m_strServerName,
  366. m_combo_IpAddresses,
  367. m_iaIpAddress,
  368. m_oblIpAddresses,
  369. m_nIpAddressSel
  370. );
  371. EndWaitCursor();
  372. //
  373. // Configure dialog for either SSL or IP binding editing
  374. //
  375. CString str;
  376. VERIFY(str.LoadString(m_fIPBinding
  377. ? IDS_EDIT_MMM_TITLE
  378. : IDS_EDIT_SSL_MMM_TITLE));
  379. SetWindowText(str);
  380. VERIFY(str.LoadString(m_fIPBinding
  381. ? IDS_TCP_PORT
  382. : IDS_SSL_PORT));
  383. m_static_Port.SetWindowText(str);
  384. ActivateControl(*GetDlgItem(IDC_STATIC_HEADER_NAME), m_fIPBinding);
  385. ActivateControl(*GetDlgItem(IDC_EDIT_DOMAIN_NAME), m_fIPBinding);
  386. return TRUE;
  387. }
  388. void
  389. CMMMEditDlg::OnOK()
  390. /*++
  391. Routine Description:
  392. OK button handler. Verify values are acceptable, and change
  393. Arguments:
  394. None
  395. Return Value:
  396. None
  397. --*/
  398. {
  399. if (!UpdateData(TRUE))
  400. {
  401. return;
  402. }
  403. if (m_nPort == 0)
  404. {
  405. ::AfxMessageBox(IDS_NO_PORT);
  406. return;
  407. }
  408. CString strOldBinding(m_entry);
  409. CInstanceProps::BuildBinding(m_entry, m_iaIpAddress, m_nPort, m_strDomainName);
  410. //
  411. // Ensure the ip/address doesn't exist in the "other" binding list
  412. //
  413. if (CInstanceProps::IsPortInUse(m_strlOtherBindings, m_iaIpAddress, m_nPort))
  414. {
  415. //
  416. // Restore the old binding
  417. //
  418. m_entry = strOldBinding;
  419. ::AfxMessageBox(m_fIPBinding
  420. ? IDS_ERR_PORT_IN_USE_SSL
  421. : IDS_ERR_PORT_IN_USE_TCP);
  422. return;
  423. }
  424. if (!IsBindingUnique(m_entry, m_strlBindings))
  425. {
  426. //
  427. // Restore the old binding
  428. //
  429. m_entry = strOldBinding;
  430. ::AfxMessageBox(IDS_ERR_BINDING);
  431. return;
  432. }
  433. CDialog::OnOK();
  434. }
  435. //
  436. // Multi-multi-multi list dialog
  437. //
  438. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  439. CMMMDlg::CMMMDlg(
  440. IN LPCTSTR lpServerName,
  441. IN DWORD dwInstance,
  442. IN OUT CStringList & strlBindings,
  443. IN OUT CStringList & strlSecureBindings,
  444. IN CWnd * pParent OPTIONAL
  445. )
  446. /*++
  447. Routine Description:
  448. Constructor
  449. Arguments:
  450. CStringList & strlBindings : Service bindings
  451. CStringList & strlSecureBindings : SSL port bindings
  452. CWnd * pParent : Optional parent window
  453. Return Value:
  454. N/A
  455. --*/
  456. : CDialog(CMMMDlg::IDD, pParent),
  457. m_ListBoxRes(
  458. IDB_BINDINGS,
  459. CMMMListBox::nBitmaps
  460. ),
  461. m_list_Bindings(g_szRegKeyIP, NUM_COLUMNS(g_aIPColumns), g_aIPColumns),
  462. m_list_SSLBindings(g_szRegKeySSL, NUM_COLUMNS(g_aSSLColumns), g_aSSLColumns),
  463. m_strlBindings(),
  464. m_strlSecureBindings(),
  465. m_strServerName(lpServerName),
  466. m_fCertInstalled(IsCertInstalledOnServer(lpServerName, dwInstance)),
  467. m_fDirty(FALSE)
  468. {
  469. //{{AFX_DATA_INIT(CMMMDlg)
  470. //}}AFX_DATA_INIT
  471. m_strlBindings.AddTail(&strlBindings);
  472. m_strlSecureBindings.AddTail(&strlSecureBindings);
  473. m_list_Bindings.AttachResources(&m_ListBoxRes);
  474. m_list_SSLBindings.AttachResources(&m_ListBoxRes);
  475. }
  476. void
  477. CMMMDlg::DoDataExchange(
  478. IN CDataExchange * pDX
  479. )
  480. /*++
  481. Routine Description:
  482. Initialise/Store control data
  483. Arguments:
  484. CDataExchange * pDX - DDX/DDV control structure
  485. Return Value:
  486. None
  487. --*/
  488. {
  489. CDialog::DoDataExchange(pDX);
  490. //{{AFX_DATA_MAP(CMMMDlg)
  491. DDX_Control(pDX, IDC_BUTTON_ADD, m_button_Add);
  492. DDX_Control(pDX, IDC_BUTTON_REMOVE, m_button_Remove);
  493. DDX_Control(pDX, IDC_BUTTON_EDIT, m_button_Edit);
  494. DDX_Control(pDX, IDC_BUTTON_ADD_SSL, m_button_AddSSL);
  495. DDX_Control(pDX, IDC_BUTTON_REMOVE_SSL, m_button_RemoveSSL);
  496. DDX_Control(pDX, IDC_BUTTON_EDIT_SSL, m_button_EditSSL);
  497. DDX_Control(pDX, IDOK, m_button_OK);
  498. //}}AFX_DATA_MAP
  499. DDX_Control(pDX, IDC_LIST_MMM, m_list_Bindings);
  500. DDX_Control(pDX, IDC_LIST_SSL_MMM, m_list_SSLBindings);
  501. }
  502. BOOL
  503. CMMMDlg::OnItemChanged()
  504. /*++
  505. Routine Description:
  506. Mark that the dialog as dirty
  507. Arguments:
  508. None
  509. Return Value:
  510. TRUE if the remove button is enabled
  511. --*/
  512. {
  513. m_fDirty = TRUE;
  514. return SetControlStates();
  515. }
  516. BOOL
  517. CMMMDlg::SetControlStates()
  518. /*++
  519. Routine Description:
  520. Set the enabled state of the controls depending on the current
  521. values in the dialog
  522. Arguments:
  523. None
  524. Return Value:
  525. TRUE if the remove button is enabled
  526. --*/
  527. {
  528. BOOL fSel = m_list_Bindings.GetSelCount() > 0;
  529. m_button_Remove.EnableWindow(fSel);
  530. m_button_Edit.EnableWindow(m_list_Bindings.GetSelCount() == 1);
  531. m_button_RemoveSSL.EnableWindow(m_list_SSLBindings.GetSelCount() > 0);
  532. m_button_EditSSL.EnableWindow(m_list_SSLBindings.GetSelCount() == 1);
  533. m_button_OK.EnableWindow(m_fDirty && m_list_Bindings.GetCount() > 0);
  534. return fSel;
  535. }
  536. void
  537. CMMMDlg::AddBindings(
  538. IN CMMMListBox & list,
  539. IN CStringList & strlBindings
  540. )
  541. /*++
  542. Routine Description:
  543. Add bindings information to the specified listbox
  544. Arguments:
  545. CMMMListBox & list : MMM Listbox (SSL or IP)
  546. CStringList & strlBindings : SSL or IP bindings
  547. Return Value:
  548. None
  549. --*/
  550. {
  551. for (POSITION pos = strlBindings.GetHeadPosition(); pos != NULL; /**/)
  552. {
  553. CString & strBinding = strlBindings.GetNext(pos);
  554. list.AddItem(strBinding);
  555. }
  556. }
  557. //
  558. // Message Map
  559. //
  560. BEGIN_MESSAGE_MAP(CMMMDlg, CDialog)
  561. //{{AFX_MSG_MAP(CMMMDlg)
  562. ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
  563. ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit)
  564. ON_BN_CLICKED(IDC_BUTTON_REMOVE, OnButtonRemove)
  565. ON_BN_CLICKED(IDC_BUTTON_ADD_SSL, OnButtonAddSsl)
  566. ON_BN_CLICKED(IDC_BUTTON_EDIT_SSL, OnButtonEditSsl)
  567. ON_BN_CLICKED(IDC_BUTTON_REMOVE_SSL, OnButtonRemoveSsl)
  568. ON_LBN_DBLCLK(IDC_LIST_MMM, OnDblclkListMmm)
  569. ON_LBN_DBLCLK(IDC_LIST_SSL_MMM, OnDblclkListSslMmm)
  570. ON_LBN_SELCHANGE(IDC_LIST_MMM, OnSelchangeListMmm)
  571. ON_LBN_SELCHANGE(IDC_LIST_SSL_MMM, OnSelchangeListSslMmm)
  572. //}}AFX_MSG_MAP
  573. END_MESSAGE_MAP()
  574. //
  575. // Message Handlers
  576. //
  577. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  578. void
  579. CMMMDlg::OnButtonAdd()
  580. /*++
  581. Routine Description:
  582. Add button handler
  583. Arguments:
  584. None
  585. Return Value:
  586. None
  587. --*/
  588. {
  589. //
  590. // Add entry
  591. //
  592. CString strEntry;
  593. CMMMEditDlg dlg(
  594. m_strServerName,
  595. m_strlBindings,
  596. m_strlSecureBindings,
  597. strEntry,
  598. TRUE, /* IP binding */
  599. this
  600. );
  601. if (dlg.DoModal() == IDOK)
  602. {
  603. POSITION pos = m_strlBindings.AddTail(strEntry);
  604. int nSel = m_list_Bindings.AddItem(m_strlBindings.GetAt(pos));
  605. m_list_Bindings.SetCurSel(nSel);
  606. OnItemChanged();
  607. }
  608. }
  609. void
  610. CMMMDlg::OnButtonEdit()
  611. /*++
  612. Routine Description:
  613. Edit button handler
  614. Arguments:
  615. None
  616. Return Value:
  617. None
  618. --*/
  619. {
  620. //
  621. // Edit entry
  622. //
  623. int nCurSel = m_list_Bindings.GetCurSel();
  624. if (nCurSel != LB_ERR)
  625. {
  626. CString & strEntry = m_list_Bindings.GetItem(nCurSel);
  627. CMMMEditDlg dlg(
  628. m_strServerName,
  629. m_strlBindings,
  630. m_strlSecureBindings,
  631. strEntry,
  632. TRUE, /* IP binding */
  633. this
  634. );
  635. if (dlg.DoModal() == IDOK)
  636. {
  637. m_list_Bindings.InvalidateSelection(nCurSel);
  638. OnItemChanged();
  639. }
  640. }
  641. }
  642. void
  643. CMMMDlg::OnButtonRemove()
  644. /*++
  645. Routine Description:
  646. Remove button handler
  647. Arguments:
  648. None
  649. Return Value:
  650. None
  651. --*/
  652. {
  653. int nCurSel = m_list_Bindings.GetCurSel();
  654. int nSel = 0;
  655. int cChanges = 0;
  656. while (nSel < m_list_Bindings.GetCount())
  657. {
  658. //
  659. // Remove Selected entry
  660. //
  661. if (m_list_Bindings.GetSel(nSel))
  662. {
  663. m_strlBindings.RemoveAt(m_strlBindings.FindIndex(nSel));
  664. m_list_Bindings.DeleteString(nSel);
  665. ++cChanges;
  666. continue;
  667. }
  668. ++nSel;
  669. }
  670. if (cChanges)
  671. {
  672. m_list_Bindings.SetCurSel(nCurSel);
  673. if (!OnItemChanged())
  674. {
  675. m_button_Add.SetFocus();
  676. }
  677. }
  678. /*
  679. //
  680. // Remove Selected entry
  681. //
  682. int nCurSel = m_list_Bindings.GetCurSel();
  683. if (nCurSel != LB_ERR)
  684. {
  685. m_strlBindings.RemoveAt(m_strlBindings.FindIndex(nCurSel));
  686. m_list_Bindings.DeleteString(nCurSel);
  687. if (nCurSel >= m_list_Bindings.GetCount())
  688. {
  689. --nCurSel;
  690. }
  691. m_list_Bindings.SetCurSel(nCurSel);
  692. if (!OnItemChanged())
  693. {
  694. m_button_Add.SetFocus();
  695. }
  696. }
  697. */
  698. }
  699. void
  700. CMMMDlg::OnDblclkListMmm()
  701. /*++
  702. Routine Description:
  703. Double click notification handler
  704. Arguments:
  705. None
  706. Return Value:
  707. None
  708. --*/
  709. {
  710. OnButtonEdit();
  711. }
  712. void
  713. CMMMDlg::OnSelchangeListMmm()
  714. /*++
  715. Routine Description:
  716. selection change notification handler
  717. Arguments:
  718. None
  719. Return Value:
  720. None
  721. --*/
  722. {
  723. SetControlStates();
  724. }
  725. void
  726. CMMMDlg::OnButtonAddSsl()
  727. /*++
  728. Routine Description:
  729. 'Add SSL' button handler
  730. Arguments:
  731. None
  732. Return Value:
  733. None
  734. --*/
  735. {
  736. //
  737. // Add entry
  738. //
  739. CString strEntry;
  740. CMMMEditDlg dlg(
  741. m_strServerName,
  742. m_strlSecureBindings,
  743. m_strlBindings,
  744. strEntry,
  745. FALSE, /* SSL binding */
  746. this
  747. );
  748. if (dlg.DoModal() == IDOK)
  749. {
  750. POSITION pos = m_strlSecureBindings.AddTail(strEntry);
  751. int nSel = m_list_SSLBindings.AddItem(m_strlSecureBindings.GetAt(pos));
  752. m_list_SSLBindings.SetCurSel(nSel);
  753. OnItemChanged();
  754. }
  755. }
  756. void
  757. CMMMDlg::OnButtonEditSsl()
  758. /*++
  759. Routine Description:
  760. 'Edit SSL' button handler
  761. Arguments:
  762. None
  763. Return Value:
  764. None
  765. --*/
  766. {
  767. //
  768. // Edit entry
  769. //
  770. int nCurSel = m_list_SSLBindings.GetCurSel();
  771. if (nCurSel != LB_ERR)
  772. {
  773. CString & strEntry = m_list_SSLBindings.GetItem(nCurSel);
  774. CMMMEditDlg dlg(
  775. m_strServerName,
  776. m_strlSecureBindings,
  777. m_strlBindings,
  778. strEntry,
  779. FALSE, /* SSL binding */
  780. this
  781. );
  782. if (dlg.DoModal() == IDOK)
  783. {
  784. m_list_SSLBindings.InvalidateSelection(nCurSel);
  785. OnItemChanged();
  786. }
  787. }
  788. }
  789. void
  790. CMMMDlg::OnButtonRemoveSsl()
  791. /*++
  792. Routine Description:
  793. 'Remove SSL' button handler
  794. Arguments:
  795. None
  796. Return Value:
  797. None
  798. --*/
  799. {
  800. int nCurSel = m_list_SSLBindings.GetCurSel();
  801. int nSel = 0;
  802. int cChanges = 0;
  803. while (nSel < m_list_SSLBindings.GetCount())
  804. {
  805. //
  806. // Remove Selected entry
  807. //
  808. if (m_list_SSLBindings.GetSel(nSel))
  809. {
  810. m_strlSecureBindings.RemoveAt(m_strlSecureBindings.FindIndex(nSel));
  811. m_list_SSLBindings.DeleteString(nSel);
  812. ++cChanges;
  813. continue;
  814. }
  815. ++nSel;
  816. }
  817. if (cChanges)
  818. {
  819. m_list_SSLBindings.SetCurSel(nCurSel);
  820. OnItemChanged();
  821. if (m_list_SSLBindings.GetSelCount() == 0)
  822. {
  823. //
  824. // Remove will be disabled
  825. //
  826. m_button_AddSSL.SetFocus();
  827. }
  828. }
  829. /*
  830. //
  831. // Remove Selected entry
  832. //
  833. int nCurSel = m_list_SSLBindings.GetCurSel();
  834. if (nCurSel != LB_ERR)
  835. {
  836. m_strlSecureBindings.RemoveAt(m_strlSecureBindings.FindIndex(nCurSel));
  837. m_list_SSLBindings.DeleteString(nCurSel);
  838. if (nCurSel >= m_list_SSLBindings.GetCount())
  839. {
  840. --nCurSel;
  841. }
  842. m_list_SSLBindings.SetCurSel(nCurSel);
  843. OnItemChanged();
  844. if (m_list_SSLBindings.GetCurSel() == LB_ERR)
  845. {
  846. //
  847. // Remove will be disabled
  848. //
  849. m_button_AddSSL.SetFocus();
  850. }
  851. }
  852. */
  853. }
  854. void
  855. CMMMDlg::OnDblclkListSslMmm()
  856. /*++
  857. Routine Description:
  858. SSL List 'double click' handler
  859. Arguments:
  860. None
  861. Return Value:
  862. None
  863. --*/
  864. {
  865. OnButtonEditSsl();
  866. }
  867. void
  868. CMMMDlg::OnSelchangeListSslMmm()
  869. /*++
  870. Routine Description:
  871. SSL List 'selection change' handler
  872. Arguments:
  873. None
  874. Return Value:
  875. None
  876. --*/
  877. {
  878. SetControlStates();
  879. }
  880. BOOL
  881. CMMMDlg::OnInitDialog()
  882. /*++
  883. Routine Description:
  884. WM_INITDIALOG handler. Initialize the dialog.
  885. Arguments:
  886. None.
  887. Return Value:
  888. TRUE if focus is to be set automatically, FALSE if the focus
  889. is already set.
  890. --*/
  891. {
  892. CDialog::OnInitDialog();
  893. m_list_Bindings.Initialize();
  894. m_list_SSLBindings.Initialize();
  895. AddBindings(m_list_Bindings, m_strlBindings);
  896. AddBindings(m_list_SSLBindings, m_strlSecureBindings);
  897. //
  898. // No certificates, no SSL
  899. //
  900. GetDlgItem(IDC_GROUP_SSL)->EnableWindow(m_fCertInstalled);
  901. m_list_SSLBindings.EnableWindow(m_fCertInstalled);
  902. m_button_AddSSL.EnableWindow(m_fCertInstalled);
  903. m_button_RemoveSSL.EnableWindow(m_fCertInstalled);
  904. m_button_EditSSL.EnableWindow(m_fCertInstalled);
  905. SetControlStates();
  906. return TRUE;
  907. }