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.

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