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.

763 lines
15 KiB

  1. /*++
  2. Copyright (c) 1994-1999 Microsoft Corporation
  3. Module Name :
  4. fservic.cpp
  5. Abstract:
  6. FTP Service Property Page
  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 "inetprop.h"
  19. #include "InetMgrApp.h"
  20. #include "shts.h"
  21. #include "ftpsht.h"
  22. #include "fservic.h"
  23. #include "usersess.h"
  24. #include "iisobj.h"
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char BASED_CODE THIS_FILE[] = __FILE__;
  28. #endif
  29. //
  30. // Some sanity values on max connections
  31. //
  32. #define MAX_MAX_CONNECTIONS (2000000001L)
  33. #define INITIAL_MAX_CONNECTIONS ( 1000L)
  34. #define UNLIMITED_CONNECTIONS (2000000000L)
  35. #define MAX_TIMEOUT (0x7FFFFFFF)
  36. #define LIMITED_CONNECTIONS_MIN (10)
  37. #define LIMITED_CONNECTIONS_MAX (40)
  38. IMPLEMENT_DYNCREATE(CFtpServicePage, CInetPropertyPage)
  39. CFtpServicePage::CFtpServicePage(
  40. IN CInetPropertySheet * pSheet
  41. )
  42. /*++
  43. Routine Description:
  44. Constructor for FTP service property page
  45. Arguments:
  46. CInetPropertySheet * pSheet : Associated property sheet
  47. Return Value:
  48. N/A
  49. --*/
  50. : CInetPropertyPage(CFtpServicePage::IDD, pSheet)
  51. {
  52. #ifdef _DEBUG
  53. afxMemDF |= checkAlwaysMemDF;
  54. #endif // _DEBUG
  55. #if 0 // Keep Class Wizard happy
  56. //{{AFX_DATA_INIT(CFtpServicePage)
  57. m_strComment = _T("");
  58. m_nTCPPort = 20;
  59. m_nUnlimited = RADIO_LIMITED;
  60. m_nIpAddressSel = -1;
  61. m_fEnableLogging = FALSE;
  62. //}}AFX_DATA_INIT
  63. m_nMaxConnections = 50;
  64. m_nVisibleMaxConnections = 50;
  65. m_nConnectionTimeOut = 600;
  66. m_iaIpAddress = (LONG)0L;
  67. m_strDomainName = _T("");
  68. #endif // 0
  69. }
  70. CFtpServicePage::~CFtpServicePage()
  71. /*++
  72. Routine Description:
  73. Destructor
  74. Arguments:
  75. N/A
  76. Return Value:
  77. N/A
  78. --*/
  79. {
  80. }
  81. void
  82. CFtpServicePage::DoDataExchange(
  83. IN CDataExchange * pDX
  84. )
  85. /*++
  86. Routine Description:
  87. Initialise/Store control data
  88. Arguments:
  89. CDataExchange * pDX - DDX/DDV control structure
  90. Return Value:
  91. None
  92. --*/
  93. {
  94. CInetPropertyPage::DoDataExchange(pDX);
  95. if (!pDX->m_bSaveAndValidate)
  96. {
  97. m_fEnableLogging = LoggingEnabled(m_dwLogType);
  98. }
  99. //{{AFX_DATA_MAP(CFtpServicePage)
  100. DDX_Radio(pDX, IDC_RADIO_UNLIMITED, m_nUnlimited);
  101. DDX_Check(pDX, IDC_CHECK_ENABLE_LOGGING, m_fEnableLogging);
  102. DDX_Text(pDX, IDC_EDIT_COMMENT, m_strComment);
  103. DDV_MinMaxChars(pDX, m_strComment, 0, MAX_PATH);
  104. DDX_Control(pDX, IDC_EDIT_MAX_CONNECTIONS, m_edit_MaxConnections);
  105. DDX_Control(pDX, IDC_STATIC_LOG_PROMPT, m_static_LogPrompt);
  106. DDX_Control(pDX, IDC_BUTTON_PROPERTIES, m_button_LogProperties);
  107. DDX_Control(pDX, IDC_COMBO_IP_ADDRESS, m_combo_IpAddresses);
  108. DDX_Control(pDX, IDC_COMBO_LOG_FORMATS, m_combo_LogFormats);
  109. //}}AFX_DATA_MAP
  110. if (!IsMasterInstance())
  111. {
  112. // This Needs to come before DDX_Text which will try to put text big number into small number
  113. DDV_MinMaxBalloon(pDX, IDC_EDIT_TCP_PORT, 1, 65535);
  114. }
  115. DDX_TextBalloon(pDX, IDC_EDIT_TCP_PORT, m_nTCPPort);
  116. if (pDX->m_bSaveAndValidate && !FetchIpAddressFromCombo(
  117. m_combo_IpAddresses,
  118. m_oblIpAddresses,
  119. m_iaIpAddress
  120. ))
  121. {
  122. pDX->Fail();
  123. }
  124. //
  125. // Private DDX/DDV Routines
  126. //
  127. int nMin = IsMasterInstance() ? 0 : 1;
  128. if (!m_f10ConnectionLimit && !m_fUnlimitedConnections)
  129. {
  130. // This Needs to come before DDX_Text which will try to put text big number into small number
  131. DDV_MinMaxBalloon(pDX, IDC_EDIT_MAX_CONNECTIONS, 0, UNLIMITED_CONNECTIONS);
  132. }
  133. if (!pDX->m_bSaveAndValidate || !m_fUnlimitedConnections )
  134. {
  135. DDX_Text(pDX, IDC_EDIT_MAX_CONNECTIONS, m_nVisibleMaxConnections);
  136. }
  137. if (m_f10ConnectionLimit)
  138. {
  139. //
  140. // Special validation for unlimited connections. We use a bogus
  141. // numeric check for data validation. Number adjustment happens
  142. // later.
  143. //
  144. if (pDX->m_bSaveAndValidate &&
  145. (m_nVisibleMaxConnections < 0 ||
  146. m_nVisibleMaxConnections > UNLIMITED_CONNECTIONS))
  147. {
  148. TCHAR szMin[32];
  149. TCHAR szMax[32];
  150. wsprintf(szMin, _T("%ld"), 0);
  151. wsprintf(szMax, _T("%ld"), 40);
  152. CString prompt;
  153. AfxFormatString2(prompt, AFX_IDP_PARSE_INT_RANGE, szMin, szMax);
  154. AfxMessageBox(prompt, MB_ICONEXCLAMATION);
  155. prompt.Empty(); // exception prep
  156. pDX->Fail();
  157. }
  158. }
  159. // This Needs to come before DDX_Text which will try to put text big number into small number
  160. DDV_MinMaxBalloon(pDX, IDC_EDIT_CONNECTION_TIMEOUT, nMin, MAX_TIMEOUT);
  161. DDX_Text(pDX, IDC_EDIT_CONNECTION_TIMEOUT, m_nConnectionTimeOut);
  162. if (pDX->m_bSaveAndValidate)
  163. {
  164. EnableLogging(m_dwLogType, m_fEnableLogging);
  165. }
  166. }
  167. //
  168. // Message Map
  169. //
  170. BEGIN_MESSAGE_MAP(CFtpServicePage, CInetPropertyPage)
  171. //{{AFX_MSG_MAP(CFtpServicePage)
  172. ON_BN_CLICKED(IDC_CHECK_ENABLE_LOGGING, OnCheckEnableLogging)
  173. ON_BN_CLICKED(IDC_RADIO_LIMITED, OnRadioLimited)
  174. ON_BN_CLICKED(IDC_RADIO_UNLIMITED, OnRadioUnlimited)
  175. ON_BN_CLICKED(IDC_BUTTON_CURRENT_SESSIONS, OnButtonCurrentSessions)
  176. ON_BN_CLICKED(IDC_BUTTON_PROPERTIES, OnButtonProperties)
  177. ON_WM_DESTROY()
  178. //}}AFX_MSG_MAP
  179. ON_EN_CHANGE(IDC_EDIT_TCP_PORT, OnItemChanged)
  180. ON_EN_CHANGE(IDC_EDIT_COMMENT, OnItemChanged)
  181. ON_EN_CHANGE(IDC_EDIT_MAX_CONNECTIONS, OnItemChanged)
  182. ON_EN_CHANGE(IDC_EDIT_CONNECTION_TIMEOUT, OnItemChanged)
  183. ON_CBN_EDITCHANGE(IDC_COMBO_IP_ADDRESS, OnItemChanged)
  184. ON_CBN_SELCHANGE(IDC_COMBO_IP_ADDRESS, OnItemChanged)
  185. ON_CBN_SELCHANGE(IDC_COMBO_LOG_FORMATS, OnItemChanged)
  186. END_MESSAGE_MAP()
  187. void
  188. CFtpServicePage::SetControlStates()
  189. /*++
  190. Routine Description:
  191. Set the states of the dialog control depending on its current
  192. values.
  193. Arguments:
  194. None
  195. Return Value:
  196. None
  197. --*/
  198. {
  199. if (m_edit_MaxConnections.m_hWnd)
  200. {
  201. m_edit_MaxConnections.EnableWindow(!m_fUnlimitedConnections);
  202. }
  203. }
  204. void
  205. CFtpServicePage::PopulateKnownIpAddresses()
  206. /*++
  207. Routine Description:
  208. Fill the combo box with known ip addresses
  209. Arguments:
  210. None
  211. Return Value:
  212. None
  213. --*/
  214. {
  215. BeginWaitCursor();
  216. PopulateComboWithKnownIpAddresses(
  217. QueryServerName(),
  218. m_combo_IpAddresses,
  219. m_iaIpAddress,
  220. m_oblIpAddresses,
  221. m_nIpAddressSel
  222. );
  223. EndWaitCursor();
  224. }
  225. //
  226. // Message Handlers
  227. //
  228. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  229. BOOL
  230. CFtpServicePage::OnInitDialog()
  231. /*++
  232. Routine Description:
  233. WM_INITDIALOG handler. Initialize the dialog.
  234. Arguments:
  235. None.
  236. Return Value:
  237. TRUE if no focus is to be set automatically, FALSE if the focus
  238. is already set.
  239. --*/
  240. {
  241. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  242. CInetPropertyPage::OnInitDialog();
  243. //
  244. // Take our direction from a phony button
  245. //
  246. CRect rc(0, 0, 0, 0);
  247. m_ocx_LogProperties.Create(
  248. _T("LogUI"),
  249. WS_BORDER,
  250. rc,
  251. this,
  252. IDC_LOGUICTRL
  253. );
  254. //
  255. // Initialize the logging ocx; pass it the metabase path of the
  256. // virtual server.
  257. // TODO: Rewrite this crappy logui control to make it more predictable.
  258. // Here metabase path should not contain leading / and trailing Root
  259. //
  260. CString path_inst = QueryMetaPath();
  261. CString path;
  262. if (IsMasterInstance())
  263. {
  264. CMetabasePath::GetServicePath(path_inst, path);
  265. }
  266. else
  267. {
  268. CMetabasePath::GetInstancePath(path_inst, path);
  269. }
  270. if (path[0] == _T('/'))
  271. {
  272. path = path.Right(path.GetLength() - 1);
  273. }
  274. m_ocx_LogProperties.SetAdminTarget(QueryServerName(), path);
  275. m_ocx_LogProperties.SetUserData(QueryAuthInfo()->QueryUserName(), QueryAuthInfo()->QueryPassword());
  276. m_ocx_LogProperties.SetComboBox(m_combo_LogFormats.m_hWnd);
  277. GetDlgItem(IDC_RADIO_UNLIMITED)->EnableWindow(!m_f10ConnectionLimit);
  278. if (IsMasterInstance() || !HasAdminAccess())
  279. {
  280. GetDlgItem(IDC_STATIC_IPADDRESS)->EnableWindow(FALSE);
  281. GetDlgItem(IDC_STATIC_TCP_PORT)->EnableWindow(FALSE);
  282. GetDlgItem(IDC_EDIT_TCP_PORT)->EnableWindow(FALSE);
  283. m_combo_IpAddresses.EnableWindow(FALSE);
  284. GetDlgItem(IDC_STATIC_DESCRIPTION)->EnableWindow(FALSE);
  285. GetDlgItem(IDC_EDIT_COMMENT)->EnableWindow(FALSE);
  286. }
  287. PopulateKnownIpAddresses();
  288. SetControlStates();
  289. SetLogState();
  290. GetDlgItem(IDC_BUTTON_CURRENT_SESSIONS)->EnableWindow(!IsMasterInstance());
  291. return TRUE;
  292. }
  293. /* virtual */
  294. HRESULT
  295. CFtpServicePage::FetchLoadedValues()
  296. /*++
  297. Routine Description:
  298. Move configuration data from sheet to dialog controls
  299. Arguments:
  300. None
  301. Return Value:
  302. HRESULT
  303. --*/
  304. {
  305. CError err;
  306. m_f10ConnectionLimit = Has10ConnectionLimit();
  307. BEGIN_META_INST_READ(CFtpSheet)
  308. FETCH_INST_DATA_FROM_SHEET(m_nMaxConnections);
  309. FETCH_INST_DATA_FROM_SHEET(m_nConnectionTimeOut);
  310. FETCH_INST_DATA_FROM_SHEET(m_iaIpAddress);
  311. FETCH_INST_DATA_FROM_SHEET(m_nTCPPort);
  312. FETCH_INST_DATA_FROM_SHEET(m_strDomainName);
  313. FETCH_INST_DATA_FROM_SHEET(m_strComment);
  314. FETCH_INST_DATA_FROM_SHEET(m_dwLogType);
  315. m_fUnlimitedConnections = m_nMaxConnections >= MAX_MAX_CONNECTIONS;
  316. if (m_f10ConnectionLimit)
  317. {
  318. m_fUnlimitedConnections = FALSE;
  319. if ((LONG)m_nMaxConnections > LIMITED_CONNECTIONS_MAX)
  320. {
  321. m_nMaxConnections = LIMITED_CONNECTIONS_MAX;
  322. }
  323. }
  324. m_nVisibleMaxConnections = m_fUnlimitedConnections
  325. ? INITIAL_MAX_CONNECTIONS
  326. : m_nMaxConnections;
  327. //
  328. // Set radio value
  329. //
  330. m_nUnlimited = m_fUnlimitedConnections ? RADIO_UNLIMITED : RADIO_LIMITED;
  331. m_nOldTCPPort = m_nTCPPort;
  332. END_META_INST_READ(err)
  333. return err;
  334. }
  335. HRESULT
  336. CFtpServicePage::SaveInfo()
  337. /*++
  338. Routine Description:
  339. Save the information on this property page
  340. Arguments:
  341. None
  342. Return Value:
  343. Error return code
  344. --*/
  345. {
  346. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  347. ASSERT(IsDirty());
  348. TRACEEOLID("Saving FTP service page now...");
  349. CError err;
  350. m_nMaxConnections = m_fUnlimitedConnections
  351. ? MAX_MAX_CONNECTIONS : m_nVisibleMaxConnections;
  352. //
  353. // Check to make sure we're not violating the license
  354. // agreement
  355. //
  356. if (m_f10ConnectionLimit)
  357. {
  358. if (m_nMaxConnections > LIMITED_CONNECTIONS_MAX)
  359. {
  360. DoHelpMessageBox(m_hWnd,IDS_CONNECTION_LIMIT, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION, 0);
  361. m_nMaxConnections = LIMITED_CONNECTIONS_MIN;
  362. }
  363. else if (m_nMaxConnections > LIMITED_CONNECTIONS_MIN
  364. && m_nMaxConnections <= LIMITED_CONNECTIONS_MAX)
  365. {
  366. DoHelpMessageBox(m_hWnd,IDS_WRN_CONNECTION_LIMIT, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION, 0);
  367. }
  368. }
  369. CString strBinding;
  370. CStringListEx m_strlBindings;
  371. CInstanceProps::BuildBinding(
  372. strBinding,
  373. m_iaIpAddress,
  374. m_nTCPPort,
  375. m_strDomainName
  376. );
  377. m_strlBindings.AddTail(strBinding);
  378. m_ocx_LogProperties.ApplyLogSelection();
  379. BeginWaitCursor();
  380. BEGIN_META_INST_WRITE(CFtpSheet)
  381. STORE_INST_DATA_ON_SHEET(m_nMaxConnections);
  382. STORE_INST_DATA_ON_SHEET(m_nMaxConnections);
  383. STORE_INST_DATA_ON_SHEET(m_nConnectionTimeOut);
  384. STORE_INST_DATA_ON_SHEET(m_dwLogType);
  385. STORE_INST_DATA_ON_SHEET(m_strComment);
  386. STORE_INST_DATA_ON_SHEET(m_strlBindings);
  387. END_META_INST_WRITE(err)
  388. EndWaitCursor();
  389. if (err.Succeeded())
  390. {
  391. CIISMBNode * pNode = (CIISMBNode *)GetSheet()->GetParameter();
  392. ASSERT(pNode != NULL);
  393. pNode->Refresh(FALSE);
  394. }
  395. return err;
  396. }
  397. void
  398. CFtpServicePage::OnRadioLimited()
  399. /*++
  400. Routine Description:
  401. 'limited' radio button handler
  402. Arguments:
  403. None
  404. Return Value:
  405. None
  406. --*/
  407. {
  408. m_fUnlimitedConnections = FALSE;
  409. SetControlStates();
  410. m_edit_MaxConnections.SetSel(0, -1);
  411. m_edit_MaxConnections.SetFocus();
  412. OnItemChanged();
  413. }
  414. void
  415. CFtpServicePage::OnRadioUnlimited()
  416. /*++
  417. Routine Description:
  418. 'unlimited' radio button handler
  419. Arguments:
  420. None
  421. Return Value:
  422. None
  423. --*/
  424. {
  425. m_fUnlimitedConnections = TRUE;
  426. OnItemChanged();
  427. }
  428. void
  429. CFtpServicePage::OnItemChanged()
  430. /*++
  431. Routine Description:
  432. Register a change in control value on this page. Mark the page as dirty.
  433. All change messages map to this function
  434. Arguments:
  435. None
  436. Return Value:
  437. None
  438. --*/
  439. {
  440. SetControlStates();
  441. SetModified(TRUE);
  442. }
  443. void
  444. CFtpServicePage::SetLogState()
  445. /*++
  446. Routine Description:
  447. Set the enabled state of the logging controls depending on
  448. whether logging is currently enabled
  449. Arguments:
  450. None
  451. Return Value:
  452. None
  453. --*/
  454. {
  455. m_static_LogPrompt.EnableWindow(m_fEnableLogging);
  456. m_combo_LogFormats.EnableWindow(m_fEnableLogging);
  457. m_button_LogProperties.EnableWindow(m_fEnableLogging);
  458. }
  459. void
  460. CFtpServicePage::OnCheckEnableLogging()
  461. /*++
  462. Routine Description:
  463. 'Enable logging' checkbox has been toggled. Reset the state
  464. of the dialog
  465. Arguments:
  466. None
  467. Return Value:
  468. None
  469. --*/
  470. {
  471. m_fEnableLogging = !m_fEnableLogging;
  472. SetLogState();
  473. OnItemChanged();
  474. }
  475. void
  476. CFtpServicePage::OnButtonProperties()
  477. /*++
  478. Routine Description:
  479. Pass on "log properties" button click to the ocx.
  480. Arguments:
  481. None
  482. Return Value:
  483. None
  484. --*/
  485. {
  486. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  487. m_ocx_LogProperties.DoClick();
  488. }
  489. void
  490. CFtpServicePage::OnButtonCurrentSessions()
  491. /*++
  492. Routine Description:
  493. 'Current Sessions' button has been pressed. Bring up the current
  494. sessions dialog
  495. Arguments:
  496. None
  497. Return Value:
  498. None
  499. -*/
  500. {
  501. CComAuthInfo * pAuth = GetSheet()->QueryAuthInfo();
  502. ASSERT(pAuth != NULL);
  503. CUserSessionsDlg dlg(
  504. pAuth->QueryServerName(),
  505. QueryInstance(),
  506. pAuth->QueryUserName(),
  507. pAuth->QueryPassword(),
  508. this,
  509. GetSheet()->IsLocal()
  510. );
  511. dlg.DoModal();
  512. }
  513. void
  514. CFtpServicePage::OnDestroy()
  515. /*++
  516. Routine Description:
  517. WM_DESTROY handler. Clean up internal data
  518. Arguments:
  519. None
  520. Return Value:
  521. None
  522. --*/
  523. {
  524. CInetPropertyPage::OnDestroy();
  525. if (m_ocx_LogProperties.m_hWnd)
  526. {
  527. m_ocx_LogProperties.Terminate();
  528. }
  529. }