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.

788 lines
15 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. vdir.cpp
  5. Abstract:
  6. FTP Virtual Directory Properties dialog
  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 "fscfg.h"
  18. #include "vdir.h"
  19. #include "dirbrows.h"
  20. #include <lmcons.h>
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. //
  27. // Directory Properties Page
  28. //
  29. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  30. IMPLEMENT_DYNCREATE(CFtpDirectoryPage, CInetPropertyPage)
  31. CFtpDirectoryPage::CFtpDirectoryPage(
  32. IN CInetPropertySheet * pSheet,
  33. IN BOOL fHome
  34. )
  35. /*++
  36. Routine Description:
  37. Constructor for directory property page
  38. Arguments:
  39. CInetPropertySheet * pSheet : Sheet pointer
  40. BOOL fHome : TRUE if this is a home directory
  41. --*/
  42. : CInetPropertyPage(CFtpDirectoryPage::IDD, pSheet,
  43. fHome ? IDS_TAB_HOME_DIRECTORY : IDS_TAB_VIRTUAL_DIRECTORY),
  44. m_fHome(fHome),
  45. m_fOriginallyUNC(FALSE)
  46. {
  47. VERIFY(m_strPathPrompt.LoadString(IDS_PATH));
  48. VERIFY(m_strSharePrompt.LoadString(IDS_SHARE));
  49. #if 0 // Keep Class-wizard happy
  50. //{{AFX_DATA_INIT(CFtpDirectoryPage)
  51. m_nPathType = RADIO_DIRECTORY;
  52. m_nUnixDos = 0;
  53. m_fRead = FALSE;
  54. m_fWrite = FALSE;
  55. m_fLogAccess = FALSE;
  56. m_strPath = _T("");
  57. m_strDefaultDocument = _T("");
  58. m_strFooter = _T("");
  59. m_fBrowsingAllowed = FALSE;
  60. m_fEnableDefaultDocument = FALSE;
  61. m_fEnableFooter = FALSE;
  62. m_dwAccessPerms = 0;
  63. //}}AFX_DATA_INIT
  64. #endif // 0
  65. }
  66. CFtpDirectoryPage::~CFtpDirectoryPage()
  67. /*++
  68. Routine Description:
  69. Destructor
  70. Arguments:
  71. N/A
  72. Return Value:
  73. N/A
  74. --*/
  75. {
  76. }
  77. void
  78. CFtpDirectoryPage::DoDataExchange(
  79. IN CDataExchange * pDX
  80. )
  81. /*++
  82. Routine Description:
  83. Initialise/Store control Data
  84. Arguments:
  85. CDataExchange * pDX : DDX/DDV struct
  86. Return Value:
  87. None.
  88. --*/
  89. {
  90. CInetPropertyPage::DoDataExchange(pDX);
  91. //{{AFX_DATA_MAP(CFtpDirectoryPage)
  92. DDX_Check(pDX, IDC_CHECK_READ, m_fRead);
  93. DDX_Check(pDX, IDC_CHECK_WRITE, m_fWrite);
  94. DDX_Check(pDX, IDC_CHECK_LOG_ACCESS, m_fLogAccess);
  95. DDX_Control(pDX, IDC_CHECK_LOG_ACCESS, m_check_LogAccess);
  96. DDX_Control(pDX, IDC_CHECK_WRITE, m_check_Write);
  97. DDX_Control(pDX, IDC_CHECK_READ, m_check_Read);
  98. DDX_Control(pDX, IDC_BUTTON_EDIT_PATH_TYPE, m_button_AddPathType);
  99. DDX_Control(pDX, IDC_BUTTON_BROWSE, m_button_Browse);
  100. DDX_Control(pDX, IDC_EDIT_PATH, m_edit_Path);
  101. DDX_Control(pDX, IDC_RADIO_DIR, m_radio_Dir);
  102. DDX_Control(pDX, IDC_STATIC_PATH, m_static_PathPrompt);
  103. DDX_Radio(pDX, IDC_RADIO_DIR, m_nPathType);
  104. DDX_Radio(pDX, IDC_RADIO_UNIX, m_nUnixDos);
  105. //}}AFX_DATA_MAP
  106. DDX_Control(pDX, IDC_RADIO_UNC, m_radio_Unc);
  107. DDX_Text(pDX, IDC_EDIT_PATH, m_strPath);
  108. m_strPath.TrimLeft();
  109. DDV_MinMaxChars(pDX, m_strPath, 0, MAX_PATH);
  110. if (pDX->m_bSaveAndValidate)
  111. {
  112. // Make sure a field names are correct
  113. //
  114. if (m_nPathType == RADIO_NETDIRECTORY)
  115. {
  116. DDX_Text(pDX, IDC_EDIT_PATH, m_strPath);
  117. m_strPath.TrimLeft();
  118. DDV_MinMaxChars(pDX, m_strPath, 0, MAX_PATH);
  119. if (!IsUNCName(m_strPath))
  120. {
  121. ::AfxMessageBox(IDS_BAD_UNC_PATH);
  122. pDX->Fail();
  123. }
  124. /*
  125. ISSUE: Supposedly this is not necessary...
  126. if (m_strUserName.IsEmpty())
  127. {
  128. ::AfxMessageBox(IDS_ERR_NO_USERNAME);
  129. OnButtonEditPathType();
  130. pDX->Fail();
  131. }
  132. */
  133. }
  134. else // Local Directory
  135. {
  136. ASSERT(m_nPathType == RADIO_DIRECTORY);
  137. if (!IsMasterInstance())
  138. {
  139. DDV_MinMaxChars(pDX, m_strPath, 1, MAX_PATH);
  140. }
  141. else
  142. {
  143. if (m_strPath.IsEmpty())
  144. {
  145. //
  146. // No additional validation necc. on master
  147. // instance.
  148. //
  149. return;
  150. }
  151. }
  152. if (!IsFullyQualifiedPath(m_strPath) && !IsDevicePath(m_strPath))
  153. {
  154. ::AfxMessageBox(IDS_ERR_INVALID_PATH);
  155. pDX->Fail();
  156. }
  157. if (IsLocal())
  158. {
  159. DWORD dwAttr = GetFileAttributes(m_strPath);
  160. if (dwAttr == 0xffffffff || (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0)
  161. {
  162. ::AfxMessageBox(IDS_ERR_PATH_NOT_FOUND);
  163. pDX->Fail();
  164. }
  165. }
  166. }
  167. }
  168. else
  169. {
  170. if (!IsMasterInstance())
  171. {
  172. DDV_MinMaxChars(pDX, m_strPath, 1, MAX_PATH);
  173. }
  174. }
  175. }
  176. void
  177. CFtpDirectoryPage::SetStateByType()
  178. /*++
  179. Routine Description:
  180. Set the state of the dialog by the path type currently selected
  181. Arguments:
  182. None
  183. Return Value:
  184. None
  185. --*/
  186. {
  187. switch(m_nPathType)
  188. {
  189. case RADIO_DIRECTORY:
  190. DeActivateControl(m_button_AddPathType);
  191. if (IsLocal() && !IsMasterInstance() && HasAdminAccess())
  192. ActivateControl(m_button_Browse);
  193. else
  194. DeActivateControl(m_button_Browse);
  195. m_static_PathPrompt.SetWindowText(m_strPathPrompt);
  196. break;
  197. case RADIO_NETDIRECTORY:
  198. ActivateControl(m_button_AddPathType);
  199. DeActivateControl(m_button_Browse);
  200. m_static_PathPrompt.SetWindowText(m_strSharePrompt);
  201. break;
  202. default:
  203. ASSERT(FALSE && "Invalid Selection");
  204. }
  205. }
  206. void
  207. CFtpDirectoryPage::SetPathType(
  208. IN LPCTSTR lpstrPath
  209. )
  210. /*++
  211. Routine Description:
  212. Set path type from given path
  213. Arguments:
  214. LPCTSTR lpstrPath : Path string
  215. Return Value:
  216. None
  217. --*/
  218. {
  219. if (::IsUNCName(lpstrPath))
  220. {
  221. m_nPathType = RADIO_NETDIRECTORY;
  222. m_radio_Dir.SetCheck(0);
  223. m_radio_Unc.SetCheck(1);
  224. }
  225. else
  226. {
  227. m_nPathType = RADIO_DIRECTORY;
  228. m_radio_Unc.SetCheck(0);
  229. m_radio_Dir.SetCheck(1);
  230. }
  231. SetStateByType();
  232. }
  233. //
  234. // Message Map
  235. //
  236. BEGIN_MESSAGE_MAP(CFtpDirectoryPage, CInetPropertyPage)
  237. //{{AFX_MSG_MAP(CFtpDirectoryPage)
  238. ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnButtonBrowse)
  239. ON_BN_CLICKED(IDC_BUTTON_EDIT_PATH_TYPE, OnButtonEditPathType)
  240. ON_BN_CLICKED(IDC_RADIO_DIR, OnRadioDir)
  241. ON_BN_CLICKED(IDC_RADIO_UNC, OnRadioUnc)
  242. //}}AFX_MSG_MAP
  243. ON_EN_CHANGE(IDC_EDIT_ALIAS, OnItemChanged)
  244. ON_EN_CHANGE(IDC_EDIT_PATH, OnItemChanged)
  245. ON_BN_CLICKED(IDC_CHECK_WRITE, OnItemChanged)
  246. ON_BN_CLICKED(IDC_CHECK_READ, OnItemChanged)
  247. ON_BN_CLICKED(IDC_CHECK_LOG_ACCESS, OnItemChanged)
  248. ON_BN_CLICKED(IDC_RADIO_MSDOS, OnItemChanged)
  249. ON_BN_CLICKED(IDC_RADIO_UNIX, OnItemChanged)
  250. END_MESSAGE_MAP()
  251. //
  252. // Message Handlers
  253. //
  254. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  255. void
  256. CFtpDirectoryPage::OnItemChanged()
  257. /*++
  258. Routine Description:
  259. Handle change in data on the item
  260. Arguments:
  261. None
  262. Return Value:
  263. None
  264. --*/
  265. {
  266. SetModified(TRUE);
  267. }
  268. void
  269. CFtpDirectoryPage::OnButtonBrowse()
  270. /*++
  271. Routine Description:
  272. "Browse" button handler
  273. Arguments:
  274. None
  275. Return Value:
  276. None
  277. --*/
  278. {
  279. ASSERT(IsLocal());
  280. CString str;
  281. m_edit_Path.GetWindowText(str);
  282. CDirBrowseDlg dlgBrowse(this, str);
  283. if (dlgBrowse.DoModal() == IDOK)
  284. {
  285. m_edit_Path.SetWindowText(dlgBrowse.GetFullPath(m_strPath));
  286. SetPathType(m_strPath);
  287. OnItemChanged();
  288. }
  289. }
  290. BOOL
  291. CFtpDirectoryPage::OnInitDialog()
  292. /*++
  293. Routine Description:
  294. WM_INITDIALOG handler. Initialize the dialog.
  295. Arguments:
  296. None.
  297. Return Value:
  298. TRUE if no focus is to be set automatically, FALSE if the focus
  299. is already set.
  300. --*/
  301. {
  302. CInetPropertyPage::OnInitDialog();
  303. m_button_Browse.EnableWindow(
  304. IsLocal()
  305. && !IsMasterInstance()
  306. && HasAdminAccess());
  307. SetPathType(m_strPath);
  308. //
  309. // Directory listing style dependent on whether or not
  310. // this is a home directory
  311. //
  312. ActivateControl(*GetDlgItem(IDC_STATIC_DIRLISTING), m_fHome);
  313. ActivateControl(*GetDlgItem(IDC_RADIO_UNIX), m_fHome);
  314. ActivateControl(*GetDlgItem(IDC_RADIO_MSDOS), m_fHome);
  315. //
  316. // Some items not available on master instance
  317. //
  318. GetDlgItem(IDC_STATIC_PATH_TYPE)->EnableWindow(!IsMasterInstance());
  319. GetDlgItem(IDC_RADIO_DIR)->EnableWindow(
  320. !IsMasterInstance() && HasAdminAccess());
  321. GetDlgItem(IDC_RADIO_UNC)->EnableWindow(
  322. !IsMasterInstance() && HasAdminAccess());
  323. GetDlgItem(IDC_STATIC_PATH)->EnableWindow(
  324. !IsMasterInstance());
  325. GetDlgItem(IDC_EDIT_PATH)->EnableWindow(
  326. !IsMasterInstance() && HasAdminAccess());
  327. GetDlgItem(IDC_BUTTON_EDIT_PATH_TYPE)->EnableWindow(
  328. !IsMasterInstance() && HasAdminAccess());
  329. m_check_Write.EnableWindow(HasAdminAccess());
  330. m_check_Read.EnableWindow(HasAdminAccess());
  331. //
  332. // Store the original value of fUNC of reference later when
  333. // saving out --BoydM
  334. //
  335. m_fOriginallyUNC = (m_nPathType == RADIO_NETDIRECTORY);
  336. return TRUE;
  337. }
  338. void
  339. CFtpDirectoryPage::ChangeTypeTo(
  340. IN int nNewType
  341. )
  342. /*++
  343. Routine Description
  344. Change the directory type
  345. Arguments:
  346. int nNewType : New radio value
  347. Return Value:
  348. None
  349. --*/
  350. {
  351. int nOldType = m_nPathType;
  352. m_nPathType = nNewType;
  353. if (nOldType == m_nPathType)
  354. {
  355. //
  356. // No change
  357. //
  358. return;
  359. }
  360. OnItemChanged();
  361. SetStateByType();
  362. LPCTSTR lpKeepPath = NULL;
  363. int nID = -1;
  364. switch(m_nPathType)
  365. {
  366. case RADIO_DIRECTORY:
  367. if (IsFullyQualifiedPath(m_strPath) || IsDevicePath(m_strPath))
  368. {
  369. //
  370. // The old path info is acceptable, propose it
  371. // as a default
  372. //
  373. lpKeepPath = m_strPath;
  374. }
  375. nID = IDS_DIRECTORY_MASK;
  376. break;
  377. case RADIO_NETDIRECTORY:
  378. if (IsUNCName(m_strPath))
  379. {
  380. //
  381. // The old path info is acceptable, propose it
  382. // as a default
  383. //
  384. lpKeepPath = m_strPath;
  385. }
  386. nID = IDS_UNC_MASK;
  387. break;
  388. }
  389. if (lpKeepPath != NULL)
  390. {
  391. //
  392. // Restore the old path
  393. //
  394. m_edit_Path.SetWindowText(lpKeepPath);
  395. }
  396. else
  397. {
  398. //
  399. // Load mask resource, and display
  400. // this in the directory
  401. //
  402. CString str;
  403. VERIFY(str.LoadString(nID));
  404. m_edit_Path.SetWindowText(str);
  405. }
  406. m_edit_Path.SetSel(0,-1);
  407. m_edit_Path.SetFocus();
  408. }
  409. void
  410. CFtpDirectoryPage::OnRadioDir()
  411. /*++
  412. Routine Description:
  413. 'directory' radio button handler
  414. Arguments:
  415. None
  416. Return Value:
  417. None.
  418. --*/
  419. {
  420. ChangeTypeTo(RADIO_DIRECTORY);
  421. }
  422. void
  423. CFtpDirectoryPage::OnRadioUnc()
  424. /*++
  425. Routine Description:
  426. 'network directory' radio button handler
  427. Arguments:
  428. None
  429. Return Value:
  430. None.
  431. --*/
  432. {
  433. ChangeTypeTo(RADIO_NETDIRECTORY);
  434. }
  435. /* virtual */
  436. HRESULT
  437. CFtpDirectoryPage::FetchLoadedValues()
  438. /*++
  439. Routine Description:
  440. Move configuration data from sheet to dialog controls
  441. Arguments:
  442. None
  443. Return Value:
  444. HRESULT
  445. --*/
  446. {
  447. CError err;
  448. BEGIN_META_DIR_READ(CFtpSheet)
  449. //
  450. // Use 'm_' notation because the message crackers require it.
  451. //
  452. BOOL m_fDontLog;
  453. FETCH_DIR_DATA_FROM_SHEET(m_strAlias);
  454. FETCH_DIR_DATA_FROM_SHEET(m_strUserName);
  455. FETCH_DIR_DATA_FROM_SHEET(m_strPassword);
  456. FETCH_DIR_DATA_FROM_SHEET(m_strPath);
  457. FETCH_DIR_DATA_FROM_SHEET(m_dwAccessPerms);
  458. FETCH_DIR_DATA_FROM_SHEET(m_fDontLog);
  459. m_fRead = IS_FLAG_SET(m_dwAccessPerms, MD_ACCESS_READ);
  460. m_fWrite = IS_FLAG_SET(m_dwAccessPerms, MD_ACCESS_WRITE);
  461. m_fLogAccess = !m_fDontLog;
  462. END_META_DIR_READ(err)
  463. BEGIN_META_INST_READ(CFtpSheet)
  464. BOOL m_fDosDirOutput;
  465. FETCH_INST_DATA_FROM_SHEET(m_fDosDirOutput);
  466. m_nUnixDos = m_fDosDirOutput ? RADIO_DOS : RADIO_UNIX;
  467. END_META_INST_READ(err)
  468. m_nPathType = ::IsUNCName(m_strPath)
  469. ? RADIO_NETDIRECTORY
  470. : RADIO_DIRECTORY;
  471. //
  472. // Make sure we were passed the right home directory
  473. // flag
  474. //
  475. ASSERT((m_fHome && !::lstrcmp(m_strAlias, g_cszRoot))
  476. || (!m_fHome && ::lstrcmp(m_strAlias, g_cszRoot)));
  477. return err;
  478. }
  479. /* virtual */
  480. HRESULT
  481. CFtpDirectoryPage::SaveInfo()
  482. /*++
  483. Routine Description:
  484. Save the information on this property page
  485. Arguments:
  486. None
  487. Return Value:
  488. Error return code
  489. --*/
  490. {
  491. ASSERT(IsDirty());
  492. TRACEEOLID("Saving W3 virtual directory page now...");
  493. CError err;
  494. SET_FLAG_IF(m_fRead, m_dwAccessPerms, MD_ACCESS_READ);
  495. SET_FLAG_IF(m_fWrite, m_dwAccessPerms, MD_ACCESS_WRITE);
  496. //
  497. // Use m_ notation because the message crackers require them
  498. //
  499. BOOL m_fDontLog = !m_fLogAccess;
  500. BOOL m_fDosDirOutput = (m_nUnixDos == RADIO_DOS);
  501. BOOL fUNC = (m_nPathType == RADIO_NETDIRECTORY);
  502. // BOOL fUserNameWritten = FALSE;
  503. BeginWaitCursor();
  504. BEGIN_META_DIR_WRITE(CFtpSheet)
  505. if (fUNC)
  506. {
  507. // Fix for 380353 -- sergeia
  508. // When user want to change password only the above construction doesn't work
  509. // because flag will be false -- user name is the same and not written!
  510. // STORE_DIR_DATA_ON_SHEET_REMEMBER(m_strUserName, fUserNameWritten)
  511. // if (fUserNameWritten)
  512. // {
  513. STORE_DIR_DATA_ON_SHEET(m_strUserName);
  514. STORE_DIR_DATA_ON_SHEET(m_strPassword);
  515. // }
  516. // endoffix
  517. }
  518. else
  519. {
  520. if (m_fOriginallyUNC)
  521. {
  522. FLAG_DIR_DATA_FOR_DELETION(MD_VR_USERNAME);
  523. FLAG_DIR_DATA_FOR_DELETION(MD_VR_PASSWORD);
  524. }
  525. }
  526. STORE_DIR_DATA_ON_SHEET(m_dwAccessPerms)
  527. STORE_DIR_DATA_ON_SHEET(m_fDontLog)
  528. STORE_DIR_DATA_ON_SHEET(m_strPath)
  529. END_META_DIR_WRITE(err)
  530. if (err.Succeeded())
  531. {
  532. BEGIN_META_INST_WRITE(CFtpSheet)
  533. STORE_INST_DATA_ON_SHEET(m_fDosDirOutput);
  534. END_META_INST_WRITE(err)
  535. }
  536. if (err.Succeeded())
  537. {
  538. //
  539. // This page can set the path, which can in theory
  540. // set the error state
  541. //
  542. NotifyMMC();
  543. }
  544. EndWaitCursor();
  545. return err;
  546. }
  547. void
  548. CFtpDirectoryPage::OnButtonEditPathType()
  549. /*++
  550. Routine Description:
  551. 'Connect As..." button handler
  552. Arguments:
  553. None
  554. Return Value:
  555. None
  556. --*/
  557. {
  558. CUserAccountDlg dlg(
  559. QueryServerName(),
  560. m_strUserName,
  561. m_strPassword,
  562. this
  563. );
  564. if (dlg.DoModal() == IDOK)
  565. {
  566. m_strUserName = dlg.m_strUserName;
  567. m_strPassword = dlg.m_strPassword;
  568. OnItemChanged();
  569. }
  570. }