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.

1751 lines
42 KiB

  1. /*++
  2. Copyright (c) 1994-2000 Microsoft Corporation
  3. Module Name :
  4. FtpAddNew.cpp
  5. Abstract:
  6. Implementation for classes used in creation of new FTP site and virtual directory
  7. Author:
  8. Sergei Antonov (sergeia)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. 11/8/2000 sergeia Initial creation
  13. --*/
  14. #include "stdafx.h"
  15. #include "common.h"
  16. #include "inetprop.h"
  17. #include "InetMgrApp.h"
  18. #include "iisobj.h"
  19. #include "ftpsht.h"
  20. #include "wizard.h"
  21. #include "FtpAddNew.h"
  22. #include <dsclient.h>
  23. #include <Dsgetdc.h>
  24. #ifdef _DEBUG
  25. #undef THIS_FILE
  26. static char BASED_CODE THIS_FILE[] = __FILE__;
  27. #endif
  28. #define new DEBUG_NEW
  29. #define DEF_PORT (21)
  30. #define MAX_ALIAS_NAME (240) // Ref Bug 241148
  31. HRESULT
  32. RebindInterface(OUT IN CMetaInterface * pInterface,
  33. OUT BOOL * pfContinue, IN DWORD dwCancelError);
  34. extern CComModule _Module;
  35. extern CInetmgrApp theApp;
  36. HRESULT
  37. CIISMBNode::AddFTPSite(
  38. const CSnapInObjectRootBase * pObj,
  39. DATA_OBJECT_TYPES type,
  40. DWORD * inst
  41. )
  42. {
  43. CFtpWizSettings ws(
  44. dynamic_cast<CMetaKey *>(QueryInterface()),
  45. QueryMachineName(),
  46. TRUE
  47. );
  48. ws.m_VersionMajor = m_pOwner->QueryMajorVersion();
  49. CIISWizardSheet sheet(
  50. IDB_WIZ_FTP_LEFT, IDB_WIZ_FTP_HEAD);
  51. CIISWizardBookEnd pgWelcome(
  52. IDS_FTP_NEW_SITE_WELCOME,
  53. IDS_FTP_NEW_SITE_WIZARD,
  54. IDS_FTP_NEW_SITE_BODY
  55. );
  56. CFtpWizDescription pgDescr(&ws);
  57. CFtpWizBindings pgBindings(&ws);
  58. CFtpWizUserIsolation pgUserIsolate(&ws, FALSE);
  59. CFtpWizPath pgHome(&ws, FALSE);
  60. CFtpWizUserName pgUserName(&ws, FALSE);
  61. CFtpWizUserIsolationAD pgUserIsolateAD(&ws, FALSE);
  62. CFtpWizPermissions pgPerms(&ws, FALSE);
  63. CIISWizardBookEnd pgCompletion(
  64. &ws.m_hrResult,
  65. IDS_FTP_NEW_SITE_SUCCESS,
  66. IDS_FTP_NEW_SITE_FAILURE,
  67. IDS_FTP_NEW_SITE_WIZARD
  68. );
  69. sheet.AddPage(&pgWelcome);
  70. sheet.AddPage(&pgDescr);
  71. sheet.AddPage(&pgBindings);
  72. if (GetOwner()->QueryMajorVersion() >= 6)
  73. {
  74. sheet.AddPage(&pgUserIsolate);
  75. sheet.AddPage(&pgUserIsolateAD);
  76. }
  77. sheet.AddPage(&pgHome);
  78. sheet.AddPage(&pgUserName);
  79. sheet.AddPage(&pgPerms);
  80. sheet.AddPage(&pgCompletion);
  81. CThemeContextActivator activator(theApp.GetFusionInitHandle());
  82. if (sheet.DoModal() == IDCANCEL)
  83. {
  84. return CError::HResult(ERROR_CANCELLED);
  85. }
  86. if (inst != NULL && ws.m_dwInstance != 0)
  87. {
  88. *inst = ws.m_dwInstance;
  89. }
  90. return ws.m_hrResult;
  91. }
  92. HRESULT
  93. CIISMBNode::AddFTPVDir(
  94. const CSnapInObjectRootBase * pObj,
  95. DATA_OBJECT_TYPES type,
  96. CString& alias
  97. )
  98. {
  99. CFtpWizSettings ws(
  100. dynamic_cast<CMetaKey *>(QueryInterface()),
  101. QueryMachineName(),
  102. FALSE
  103. );
  104. CComBSTR path;
  105. BuildMetaPath(path);
  106. ws.m_strParent = path;
  107. CIISWizardSheet sheet(
  108. IDB_WIZ_FTP_LEFT, IDB_WIZ_FTP_HEAD);
  109. CIISWizardBookEnd pgWelcome(
  110. IDS_FTP_NEW_VDIR_WELCOME,
  111. IDS_FTP_NEW_VDIR_WIZARD,
  112. IDS_FTP_NEW_VDIR_BODY
  113. );
  114. CFtpWizAlias pgAlias(&ws);
  115. CFtpWizPath pgHome(&ws, TRUE);
  116. CFtpWizUserName pgUserName(&ws, TRUE);
  117. CFtpWizPermissions pgPerms(&ws, TRUE);
  118. CIISWizardBookEnd pgCompletion(
  119. &ws.m_hrResult,
  120. IDS_FTP_NEW_VDIR_SUCCESS,
  121. IDS_FTP_NEW_VDIR_FAILURE,
  122. IDS_FTP_NEW_VDIR_WIZARD
  123. );
  124. sheet.AddPage(&pgWelcome);
  125. sheet.AddPage(&pgAlias);
  126. sheet.AddPage(&pgHome);
  127. sheet.AddPage(&pgUserName);
  128. sheet.AddPage(&pgPerms);
  129. sheet.AddPage(&pgCompletion);
  130. CThemeContextActivator activator(theApp.GetFusionInitHandle());
  131. if (sheet.DoModal() == IDCANCEL)
  132. {
  133. return CError::HResult(ERROR_CANCELLED);
  134. }
  135. if (SUCCEEDED(ws.m_hrResult))
  136. {
  137. alias = ws.m_strAlias;
  138. }
  139. return ws.m_hrResult;
  140. }
  141. CFtpWizSettings::CFtpWizSettings(
  142. CMetaKey * pMetaKey,
  143. LPCTSTR lpszServerName,
  144. BOOL fNewSite,
  145. DWORD dwInstance,
  146. LPCTSTR lpszParent
  147. ) :
  148. m_hrResult(S_OK),
  149. m_pKey(pMetaKey),
  150. m_fNewSite(fNewSite),
  151. m_fUNC(FALSE),
  152. m_fRead(FALSE),
  153. m_fWrite(FALSE),
  154. m_fDelegation(TRUE), // on by default
  155. m_dwInstance(dwInstance)
  156. {
  157. ASSERT(lpszServerName != NULL);
  158. m_strServerName = lpszServerName;
  159. m_fLocal = IsServerLocal(m_strServerName);
  160. if (lpszParent)
  161. {
  162. m_strParent = lpszParent;
  163. }
  164. }
  165. IMPLEMENT_DYNCREATE(CFtpWizDescription, CIISWizardPage)
  166. CFtpWizDescription::CFtpWizDescription(CFtpWizSettings * pData)
  167. : CIISWizardPage(
  168. CFtpWizDescription::IDD, IDS_FTP_NEW_SITE_WIZARD, HEADER_PAGE
  169. ),
  170. m_pSettings(pData)
  171. {
  172. }
  173. CFtpWizDescription::~CFtpWizDescription()
  174. {
  175. }
  176. //
  177. // Message Map
  178. //
  179. BEGIN_MESSAGE_MAP(CFtpWizDescription, CIISWizardPage)
  180. //{{AFX_MSG_MAP(CFtpWizDescription)
  181. ON_EN_CHANGE(IDC_EDIT_DESCRIPTION, OnChangeEditDescription)
  182. //}}AFX_MSG_MAP
  183. END_MESSAGE_MAP()
  184. void
  185. CFtpWizDescription::OnChangeEditDescription()
  186. {
  187. SetControlStates();
  188. }
  189. LRESULT
  190. CFtpWizDescription::OnWizardNext()
  191. {
  192. if (!ValidateString(m_edit_Description,
  193. m_pSettings->m_strDescription, 1, MAX_PATH))
  194. {
  195. return -1;
  196. }
  197. return CIISWizardPage::OnWizardNext();
  198. }
  199. BOOL
  200. CFtpWizDescription::OnSetActive()
  201. {
  202. SetControlStates();
  203. return CIISWizardPage::OnSetActive();
  204. }
  205. void
  206. CFtpWizDescription::DoDataExchange(CDataExchange * pDX)
  207. {
  208. CIISWizardPage::DoDataExchange(pDX);
  209. //{{AFX_DATA_MAP(CFtpWizDescription)
  210. DDX_Control(pDX, IDC_EDIT_DESCRIPTION, m_edit_Description);
  211. //}}AFX_DATA_MAP
  212. }
  213. void
  214. CFtpWizDescription::SetControlStates()
  215. {
  216. DWORD dwFlags = PSWIZB_BACK;
  217. if (m_edit_Description.GetWindowTextLength() > 0)
  218. {
  219. dwFlags |= PSWIZB_NEXT;
  220. }
  221. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  222. //SetWizardButtons(dwFlags);
  223. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, dwFlags);
  224. }
  225. ///////////////////////////////////////////
  226. //
  227. // New Virtual Directory Wizard Alias Page
  228. //
  229. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  230. IMPLEMENT_DYNCREATE(CFtpWizAlias, CIISWizardPage)
  231. CFtpWizAlias::CFtpWizAlias(
  232. IN OUT CFtpWizSettings * pSettings
  233. )
  234. /*++
  235. Routine Description:
  236. Constructor
  237. Arguments:
  238. CString & strServerName : Server name
  239. Return Value:
  240. None
  241. --*/
  242. : CIISWizardPage(
  243. CFtpWizAlias::IDD,
  244. IDS_FTP_NEW_VDIR_WIZARD,
  245. HEADER_PAGE
  246. ),
  247. m_pSettings(pSettings)
  248. //m_strAlias()
  249. {
  250. #if 0 // Keep Class Wizard Happy
  251. //{{AFX_DATA_INIT(CFtpWizAlias)
  252. m_strAlias = _T("");
  253. //}}AFX_DATA_INIT
  254. #endif // 0
  255. }
  256. CFtpWizAlias::~CFtpWizAlias()
  257. /*++
  258. Routine Description:
  259. Destructor
  260. Arguments:
  261. N/A
  262. Return Value:
  263. N/A
  264. --*/
  265. {
  266. }
  267. void
  268. CFtpWizAlias::DoDataExchange(
  269. IN CDataExchange * pDX
  270. )
  271. /*++
  272. Routine Description:
  273. Initialise/Store control data
  274. Arguments:
  275. CDataExchange * pDX - DDX/DDV control structure
  276. Return Value:
  277. None
  278. --*/
  279. {
  280. CIISWizardPage::DoDataExchange(pDX);
  281. //{{AFX_DATA_MAP(CFtpWizAlias)
  282. DDX_Control(pDX, IDC_EDIT_ALIAS, m_edit_Alias);
  283. //}}AFX_DATA_MAP
  284. }
  285. LRESULT
  286. CFtpWizAlias::OnWizardNext()
  287. /*++
  288. Routine Description:
  289. prevent the / and \ characters from being in the alias name
  290. Arguments:
  291. None
  292. Return Value:
  293. None
  294. --*/
  295. {
  296. if (!ValidateString(
  297. m_edit_Alias,
  298. m_pSettings->m_strAlias,
  299. 1,
  300. MAX_ALIAS_NAME
  301. ))
  302. {
  303. return -1;
  304. }
  305. //
  306. // Find the illegal characters. If they exist tell
  307. // the user and don't go on.
  308. //
  309. if (m_pSettings->m_strAlias.FindOneOf(_T("/\\?*")) >= 0)
  310. {
  311. EditShowBalloon(m_edit_Alias.m_hWnd, IDS_ILLEGAL_ALIAS_CHARS);
  312. //
  313. // prevent the wizard page from changing
  314. //
  315. return -1;
  316. }
  317. //
  318. // Allow the wizard to continue
  319. //
  320. return CIISWizardPage::OnWizardNext();
  321. }
  322. void
  323. CFtpWizAlias::SetControlStates()
  324. /*++
  325. Routine Description:
  326. Set the state of the control data
  327. Arguments:
  328. None
  329. Return Value:
  330. None
  331. --*/
  332. {
  333. DWORD dwFlags = PSWIZB_BACK;
  334. if (m_edit_Alias.GetWindowTextLength() > 0)
  335. {
  336. dwFlags |= PSWIZB_NEXT;
  337. }
  338. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  339. //SetWizardButtons(dwFlags);
  340. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, dwFlags);
  341. }
  342. //
  343. // Message Map
  344. //
  345. BEGIN_MESSAGE_MAP(CFtpWizAlias, CIISWizardPage)
  346. //{{AFX_MSG_MAP(CFtpWizAlias)
  347. ON_EN_CHANGE(IDC_EDIT_ALIAS, OnChangeEditAlias)
  348. //}}AFX_MSG_MAP
  349. END_MESSAGE_MAP()
  350. //
  351. // Message Handlers
  352. //
  353. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  354. BOOL
  355. CFtpWizAlias::OnSetActive()
  356. /*++
  357. Routine Description:
  358. Activation handler
  359. Arguments:
  360. None
  361. Return Value:
  362. TRUE for success, FALSE for failure
  363. --*/
  364. {
  365. SetControlStates();
  366. return CIISWizardPage::OnSetActive();
  367. }
  368. void
  369. CFtpWizAlias::OnChangeEditAlias()
  370. /*++
  371. Routine Description:
  372. 'edit change' handler
  373. Arguments:
  374. None
  375. Return Value:
  376. None
  377. --*/
  378. {
  379. SetControlStates();
  380. }
  381. ///////////////////////////////////////////
  382. IMPLEMENT_DYNCREATE(CFtpWizBindings, CIISWizardPage)
  383. CFtpWizBindings::CFtpWizBindings(
  384. IN OUT CFtpWizSettings * pSettings
  385. )
  386. : CIISWizardPage(CFtpWizBindings::IDD,
  387. IDS_FTP_NEW_SITE_WIZARD, HEADER_PAGE
  388. ),
  389. m_pSettings(pSettings),
  390. m_iaIpAddress(),
  391. m_oblIpAddresses()
  392. {
  393. //{{AFX_DATA_INIT(CFtpWizBindings)
  394. m_nTCPPort = DEF_PORT;
  395. m_nIpAddressSel = -1;
  396. //}}AFX_DATA_INIT
  397. }
  398. CFtpWizBindings::~CFtpWizBindings()
  399. {
  400. }
  401. void
  402. CFtpWizBindings::DoDataExchange(
  403. IN CDataExchange * pDX
  404. )
  405. {
  406. CIISWizardPage::DoDataExchange(pDX);
  407. //{{AFX_DATA_MAP(CFtpWizBindings)
  408. DDX_Control(pDX, IDC_COMBO_IP_ADDRESSES, m_combo_IpAddresses);
  409. // This Needs to come before DDX_Text which will try to put text big number into small number
  410. DDV_MinMaxBalloon(pDX, IDC_EDIT_TCP_PORT, 1, 65535);
  411. DDX_TextBalloon(pDX, IDC_EDIT_TCP_PORT, m_nTCPPort);
  412. //}}AFX_DATA_MAP
  413. DDX_CBIndex(pDX, IDC_COMBO_IP_ADDRESSES, m_nIpAddressSel);
  414. if (pDX->m_bSaveAndValidate)
  415. {
  416. if (!FetchIpAddressFromCombo(
  417. m_combo_IpAddresses,
  418. m_oblIpAddresses,
  419. m_iaIpAddress
  420. ))
  421. {
  422. pDX->Fail();
  423. }
  424. CString strDomain;
  425. CInstanceProps::BuildBinding(
  426. m_pSettings->m_strBinding,
  427. m_iaIpAddress,
  428. m_nTCPPort,
  429. strDomain
  430. );
  431. }
  432. }
  433. void
  434. CFtpWizBindings::SetControlStates()
  435. {
  436. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  437. //SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  438. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
  439. }
  440. //
  441. // Message Map
  442. //
  443. BEGIN_MESSAGE_MAP(CFtpWizBindings, CIISWizardPage)
  444. //{{AFX_MSG_MAP(CFtpWizBindings)
  445. //}}AFX_MSG_MAP
  446. END_MESSAGE_MAP()
  447. //
  448. // Message Handlers
  449. //
  450. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  451. BOOL
  452. CFtpWizBindings::OnInitDialog()
  453. {
  454. CIISWizardPage::OnInitDialog();
  455. BeginWaitCursor();
  456. PopulateComboWithKnownIpAddresses(
  457. m_pSettings->m_strServerName,
  458. m_combo_IpAddresses,
  459. m_iaIpAddress,
  460. m_oblIpAddresses,
  461. m_nIpAddressSel
  462. );
  463. EndWaitCursor();
  464. return TRUE;
  465. }
  466. BOOL
  467. CFtpWizBindings::OnSetActive()
  468. {
  469. SetControlStates();
  470. return CIISWizardPage::OnSetActive();
  471. }
  472. ///////////////////////////////////////////
  473. IMPLEMENT_DYNCREATE(CFtpWizPath, CIISWizardPage)
  474. CFtpWizPath::CFtpWizPath(
  475. IN OUT CFtpWizSettings * pSettings,
  476. IN BOOL bVDir
  477. )
  478. : CIISWizardPage(
  479. (bVDir ? IDD_FTP_NEW_DIR_PATH : IDD_FTP_NEW_INST_HOME),
  480. (bVDir ? IDS_FTP_NEW_VDIR_WIZARD : IDS_FTP_NEW_SITE_WIZARD),
  481. HEADER_PAGE
  482. ),
  483. m_pSettings(pSettings)
  484. {
  485. #if 0 // Keep ClassWizard happy
  486. //{{AFX_DATA_INIT(CFtpWizPath)
  487. m_strPath = _T("");
  488. //}}AFX_DATA_INIT
  489. #endif // 0
  490. }
  491. CFtpWizPath::~CFtpWizPath()
  492. {
  493. }
  494. void
  495. CFtpWizPath::DoDataExchange(
  496. IN CDataExchange * pDX
  497. )
  498. {
  499. CIISWizardPage::DoDataExchange(pDX);
  500. //{{AFX_DATA_MAP(CFtpWizPath)
  501. DDX_Control(pDX, IDC_BUTTON_BROWSE, m_button_Browse);
  502. DDX_Control(pDX, IDC_EDIT_PATH, m_edit_Path);
  503. //}}AFX_DATA_MAP
  504. DDX_Text(pDX, IDC_EDIT_PATH, m_pSettings->m_strPath);
  505. DDV_MaxCharsBalloon(pDX, m_pSettings->m_strPath, MAX_PATH);
  506. // We are not using DDV_FolderPath here -- it will be called too often
  507. }
  508. void
  509. CFtpWizPath::SetControlStates()
  510. {
  511. DWORD dwFlags = PSWIZB_BACK;
  512. if (m_edit_Path.GetWindowTextLength() > 0)
  513. {
  514. dwFlags |= PSWIZB_NEXT;
  515. }
  516. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  517. //SetWizardButtons(dwFlags);
  518. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, dwFlags);
  519. }
  520. //
  521. // Message Map
  522. //
  523. BEGIN_MESSAGE_MAP(CFtpWizPath, CIISWizardPage)
  524. //{{AFX_MSG_MAP(CFtpWizPath)
  525. ON_EN_CHANGE(IDC_EDIT_PATH, OnChangeEditPath)
  526. ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnButtonBrowse)
  527. //}}AFX_MSG_MAP
  528. END_MESSAGE_MAP()
  529. //
  530. // Message Handlers
  531. //
  532. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  533. BOOL
  534. CFtpWizPath::OnSetActive()
  535. {
  536. if (m_pSettings->m_UserIsolation == 2)
  537. {
  538. return 0;
  539. }
  540. SetControlStates();
  541. return CIISWizardPage::OnSetActive();
  542. }
  543. LRESULT
  544. CFtpWizPath::OnWizardNext()
  545. {
  546. CString csPathMunged = m_pSettings->m_strPath;
  547. if (!ValidateString(m_edit_Path, m_pSettings->m_strPath, 1, MAX_PATH))
  548. {
  549. return -1;
  550. }
  551. if (!PathIsValid(m_pSettings->m_strPath,TRUE))
  552. {
  553. m_edit_Path.SetSel(0,-1);
  554. m_edit_Path.SetFocus();
  555. EditShowBalloon(m_edit_Path.m_hWnd, IDS_ERR_BAD_PATH);
  556. return -1;
  557. }
  558. // -------------------------------------------------------------
  559. // Before we do anything we need to see if it's a "special" path
  560. //
  561. // Everything after this function must validate against csPathMunged...
  562. // this is because IsSpecialPath could have munged it...
  563. // -------------------------------------------------------------
  564. csPathMunged = m_pSettings->m_strPath;
  565. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  566. GetSpecialPathRealPath(0,m_pSettings->m_strPath,csPathMunged);
  567. #endif
  568. m_pSettings->m_fUNC = IsUNCName(csPathMunged);
  569. DWORD dwAllowed = CHKPATH_ALLOW_DEVICE_PATH;
  570. dwAllowed |= CHKPATH_ALLOW_UNC_PATH; // allow UNC type dir paths
  571. dwAllowed |= CHKPATH_ALLOW_UNC_SERVERSHARE_ONLY;
  572. // don't allow these type of paths commented out below:
  573. //dwAllowed |= CHKPATH_ALLOW_RELATIVE_PATH;
  574. //dwAllowed |= CHKPATH_ALLOW_UNC_SERVERNAME_ONLY;
  575. DWORD dwCharSet = CHKPATH_CHARSET_GENERAL;
  576. FILERESULT dwValidRet = MyValidatePath(csPathMunged,m_pSettings->m_fLocal,CHKPATH_WANT_DIR,dwAllowed,dwCharSet);
  577. if (FAILED(dwValidRet))
  578. {
  579. int ids = IDS_ERR_BAD_PATH;
  580. if (dwValidRet == CHKPATH_FAIL_NOT_ALLOWED_DIR_NOT_EXIST)
  581. {
  582. ids = IDS_ERR_PATH_NOT_FOUND;
  583. }
  584. m_edit_Path.SetSel(0,-1);
  585. m_edit_Path.SetFocus();
  586. EditShowBalloon(m_edit_Path.m_hWnd, IDS_ERR_PATH_NOT_FOUND);
  587. return -1;
  588. }
  589. return CIISWizardPage::OnWizardNext();
  590. }
  591. void
  592. CFtpWizPath::OnChangeEditPath()
  593. {
  594. SetControlStates();
  595. }
  596. static int CALLBACK
  597. FileChooserCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
  598. {
  599. CFtpWizPath * pThis = (CFtpWizPath *)lpData;
  600. ASSERT(pThis != NULL);
  601. return pThis->BrowseForFolderCallback(hwnd, uMsg, lParam);
  602. }
  603. int
  604. CFtpWizPath::BrowseForFolderCallback(HWND hwnd, UINT uMsg, LPARAM lParam)
  605. {
  606. switch (uMsg)
  607. {
  608. case BFFM_INITIALIZED:
  609. ASSERT(m_pPathTemp != NULL);
  610. if (::PathIsNetworkPath(m_pPathTemp))
  611. return 0;
  612. while (!::PathIsDirectory(m_pPathTemp))
  613. {
  614. if (0 == ::PathRemoveFileSpec(m_pPathTemp) && !::PathIsRoot(m_pPathTemp))
  615. {
  616. return 0;
  617. }
  618. DWORD attr = GetFileAttributes(m_pPathTemp);
  619. if ((attr & FILE_ATTRIBUTE_READONLY) == 0)
  620. break;
  621. }
  622. ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)m_pPathTemp);
  623. break;
  624. case BFFM_SELCHANGED:
  625. {
  626. LPITEMIDLIST pidl = (LPITEMIDLIST)lParam;
  627. TCHAR path[MAX_PATH];
  628. if (SHGetPathFromIDList(pidl, path))
  629. {
  630. ::SendMessage(hwnd, BFFM_ENABLEOK, 0, !PathIsNetworkPath(path));
  631. }
  632. }
  633. break;
  634. case BFFM_VALIDATEFAILED:
  635. break;
  636. }
  637. return 0;
  638. }
  639. void
  640. CFtpWizPath::OnButtonBrowse()
  641. {
  642. ASSERT(m_pSettings->m_fLocal);
  643. BOOL bRes = FALSE;
  644. HRESULT hr;
  645. CString str;
  646. m_edit_Path.GetWindowText(str);
  647. if (SUCCEEDED(hr = CoInitialize(NULL)))
  648. {
  649. LPITEMIDLIST pidl = NULL;
  650. if (SUCCEEDED(SHGetFolderLocation(NULL, CSIDL_DRIVES, NULL, 0, &pidl)))
  651. {
  652. LPITEMIDLIST pidList = NULL;
  653. BROWSEINFO bi;
  654. TCHAR buf[MAX_PATH];
  655. ZeroMemory(&bi, sizeof(bi));
  656. int drive = PathGetDriveNumber(str);
  657. if (GetDriveType(PathBuildRoot(buf, drive)) == DRIVE_FIXED)
  658. {
  659. StrCpy(buf, str);
  660. }
  661. else
  662. {
  663. buf[0] = 0;
  664. }
  665. m_strBrowseTitle.LoadString(m_pSettings->m_fNewSite ?
  666. IDS_FTP_NEW_SITE_WIZARD : IDS_FTP_NEW_VDIR_WIZARD);
  667. bi.hwndOwner = m_hWnd;
  668. bi.pidlRoot = pidl;
  669. bi.pszDisplayName = m_pPathTemp = buf;
  670. bi.lpszTitle = m_strBrowseTitle;
  671. bi.ulFlags |= BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS/* | BIF_EDITBOX*/;
  672. bi.lpfn = FileChooserCallback;
  673. bi.lParam = (LPARAM)this;
  674. pidList = SHBrowseForFolder(&bi);
  675. if ( pidList != NULL
  676. && SHGetPathFromIDList(pidList, buf)
  677. )
  678. {
  679. str = buf;
  680. bRes = TRUE;
  681. }
  682. IMalloc * pMalloc;
  683. VERIFY(SUCCEEDED(SHGetMalloc(&pMalloc)));
  684. if (pidl != NULL)
  685. pMalloc->Free(pidl);
  686. pMalloc->Release();
  687. }
  688. CoUninitialize();
  689. }
  690. if (bRes)
  691. {
  692. m_edit_Path.SetWindowText(str);
  693. SetControlStates();
  694. }
  695. }
  696. BOOL
  697. CFtpWizPath::OnInitDialog()
  698. {
  699. CIISWizardPage::OnInitDialog();
  700. m_button_Browse.EnableWindow(m_pSettings->m_fLocal);
  701. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  702. LimitInputPath(CONTROL_HWND(IDC_EDIT_PATH),TRUE);
  703. #else
  704. LimitInputPath(CONTROL_HWND(IDC_EDIT_PATH),FALSE);
  705. #endif
  706. return TRUE;
  707. }
  708. ///////////////////////////////////////////
  709. IMPLEMENT_DYNCREATE(CFtpWizUserName, CIISWizardPage)
  710. CFtpWizUserName::CFtpWizUserName(
  711. IN OUT CFtpWizSettings * pSettings,
  712. IN BOOL bVDir
  713. )
  714. : CIISWizardPage(
  715. CFtpWizUserName::IDD,
  716. (bVDir ? IDS_FTP_NEW_VDIR_WIZARD : IDS_FTP_NEW_SITE_WIZARD),
  717. HEADER_PAGE,
  718. (bVDir ? USE_DEFAULT_CAPTION : IDS_FTP_NEW_SITE_SECURITY_TITLE),
  719. (bVDir ? USE_DEFAULT_CAPTION : IDS_FTP_NEW_SITE_SECURITY_SUBTITLE)
  720. ),
  721. m_pSettings(pSettings)
  722. {
  723. #if 0 // Keep Class Wizard Happy
  724. //{{AFX_DATA_INIT(CFtpWizUserName)
  725. //}}AFX_DATA_INIT
  726. #endif // 0
  727. }
  728. CFtpWizUserName::~CFtpWizUserName()
  729. {
  730. }
  731. void
  732. CFtpWizUserName::DoDataExchange(
  733. IN CDataExchange * pDX
  734. )
  735. {
  736. CIISWizardPage::DoDataExchange(pDX);
  737. //{{AFX_DATA_MAP(CFtpWizUserName)
  738. DDX_Control(pDX, IDC_EDIT_USERNAME, m_edit_UserName);
  739. DDX_Control(pDX, IDC_EDIT_PASSWORD, m_edit_Password);
  740. DDX_Control(pDX, IDC_DELEGATION, m_chk_Delegation);
  741. DDX_Check(pDX, IDC_DELEGATION, m_pSettings->m_fDelegation);
  742. //}}AFX_DATA_MAP
  743. //
  744. // Private DDX/DDV Routines
  745. //
  746. DDX_Text(pDX, IDC_EDIT_USERNAME, m_pSettings->m_strUserName);
  747. if (pDX->m_bSaveAndValidate && !m_pSettings->m_fDelegation)
  748. {
  749. DDV_MaxCharsBalloon(pDX, m_pSettings->m_strUserName, UNLEN);
  750. }
  751. //
  752. // Some people have a tendency to add "\\" before
  753. // the computer name in user accounts. Fix this here.
  754. //
  755. m_pSettings->m_strUserName.TrimLeft();
  756. while (*m_pSettings->m_strUserName == '\\')
  757. {
  758. m_pSettings->m_strUserName = m_pSettings->m_strUserName.Mid(2);
  759. }
  760. if (!m_pSettings->m_fDelegation && !m_fMovingBack)
  761. {
  762. //DDX_Password(pDX, IDC_EDIT_PASSWORD, m_pSettings->m_strPassword, g_lpszDummyPassword);
  763. DDX_Password_SecuredString(pDX, IDC_EDIT_PASSWORD, m_pSettings->m_strPassword, g_lpszDummyPassword);
  764. if (pDX->m_bSaveAndValidate)
  765. {
  766. //DDV_MaxCharsBalloon(pDX, m_pSettings->m_strPassword, PWLEN);
  767. DDV_MaxCharsBalloon_SecuredString(pDX, m_pSettings->m_strPassword, PWLEN);
  768. }
  769. }
  770. }
  771. void
  772. CFtpWizUserName::SetControlStates()
  773. {
  774. DWORD dwFlags = PSWIZB_BACK;
  775. BOOL bEnable = BST_CHECKED != m_chk_Delegation.GetCheck();
  776. if (m_edit_UserName.GetWindowTextLength() > 0 || !bEnable)
  777. {
  778. dwFlags |= PSWIZB_NEXT;
  779. }
  780. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  781. //SetWizardButtons(dwFlags);
  782. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, dwFlags);
  783. m_edit_UserName.EnableWindow(bEnable);
  784. m_edit_Password.EnableWindow(bEnable);
  785. GetDlgItem(IDC_BUTTON_BROWSE_USERS)->EnableWindow(bEnable);
  786. }
  787. //
  788. // Message Map
  789. //
  790. BEGIN_MESSAGE_MAP(CFtpWizUserName, CIISWizardPage)
  791. //{{AFX_MSG_MAP(CFtpWizUserName)
  792. ON_BN_CLICKED(IDC_BUTTON_BROWSE_USERS, OnButtonBrowseUsers)
  793. ON_EN_CHANGE(IDC_EDIT_USERNAME, OnChangeEditUsername)
  794. ON_BN_CLICKED(IDC_BUTTON_CHECK_PASSWORD, OnButtonCheckPassword)
  795. ON_BN_CLICKED(IDC_DELEGATION, OnCheckDelegation)
  796. //}}AFX_MSG_MAP
  797. END_MESSAGE_MAP()
  798. //
  799. // Message Handlers
  800. //
  801. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  802. BOOL
  803. CFtpWizUserName::OnSetActive()
  804. {
  805. if ( !m_pSettings->m_fUNC
  806. || m_pSettings->m_UserIsolation == 1
  807. || m_pSettings->m_UserIsolation == 2
  808. )
  809. {
  810. return 0;
  811. }
  812. BOOL bRes = CIISWizardPage::OnSetActive();
  813. SetControlStates();
  814. return bRes;
  815. }
  816. BOOL
  817. CFtpWizUserName::OnInitDialog()
  818. {
  819. CIISWizardPage::OnInitDialog();
  820. return TRUE;
  821. }
  822. LRESULT
  823. CFtpWizUserName::OnWizardNext()
  824. {
  825. m_fMovingBack = FALSE;
  826. if (BST_CHECKED != m_chk_Delegation.GetCheck())
  827. {
  828. if (!ValidateString(m_edit_UserName, m_pSettings->m_strUserName, 1, UNLEN))
  829. {
  830. return -1;
  831. }
  832. }
  833. return CIISWizardPage::OnWizardNext();
  834. }
  835. LRESULT
  836. CFtpWizUserName::OnWizardBack()
  837. {
  838. m_fMovingBack = TRUE;
  839. return CIISWizardPage::OnWizardNext();
  840. }
  841. void
  842. CFtpWizUserName::OnButtonBrowseUsers()
  843. {
  844. CString str;
  845. if (GetIUsrAccount(m_pSettings->m_strServerName, this, str))
  846. {
  847. //
  848. // If a name was selected, blank
  849. // out the password
  850. //
  851. m_edit_UserName.SetWindowText(str);
  852. m_edit_Password.SetFocus();
  853. }
  854. }
  855. void
  856. CFtpWizUserName::OnChangeEditUsername()
  857. {
  858. m_edit_Password.SetWindowText(_T(""));
  859. SetControlStates();
  860. }
  861. void
  862. CFtpWizUserName::OnCheckDelegation()
  863. {
  864. SetControlStates();
  865. }
  866. void
  867. CFtpWizUserName::OnButtonCheckPassword()
  868. {
  869. if (!UpdateData(TRUE))
  870. {
  871. return;
  872. }
  873. CString csTempPassword;
  874. m_pSettings->m_strPassword.CopyTo(csTempPassword);
  875. CError err(CComAuthInfo::VerifyUserPassword(
  876. m_pSettings->m_strUserName,
  877. csTempPassword
  878. ));
  879. if (!err.MessageBoxOnFailure(m_hWnd))
  880. {
  881. DoHelpMessageBox(m_hWnd,IDS_PASSWORD_OK, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION, 0);
  882. }
  883. }
  884. ////////////////// User Isolation page //////////////////////////////////////////////////////
  885. IMPLEMENT_DYNCREATE(CFtpWizUserIsolation, CIISWizardPage)
  886. CFtpWizUserIsolation::CFtpWizUserIsolation(
  887. IN OUT CFtpWizSettings * pSettings,
  888. IN BOOL bVDir
  889. )
  890. : CIISWizardPage(
  891. CFtpWizUserIsolation::IDD,
  892. IDS_FTP_NEW_SITE_WIZARD,
  893. HEADER_PAGE,
  894. USE_DEFAULT_CAPTION,
  895. USE_DEFAULT_CAPTION
  896. ),
  897. m_bVDir(bVDir),
  898. m_pSettings(pSettings)
  899. {
  900. //{{AFX_DATA_INIT(CFtpWizUserIsolation)
  901. //}}AFX_DATA_INIT
  902. m_pSettings->m_UserIsolation = 0;
  903. }
  904. CFtpWizUserIsolation::~CFtpWizUserIsolation()
  905. {
  906. }
  907. void
  908. CFtpWizUserIsolation::DoDataExchange(
  909. IN CDataExchange * pDX
  910. )
  911. {
  912. CIISWizardPage::DoDataExchange(pDX);
  913. //{{AFX_DATA_MAP(CFtpWizPermissions)
  914. //}}AFX_DATA_MAP
  915. DDX_Radio(pDX, IDC_NO_ISOLATION, m_pSettings->m_UserIsolation);
  916. }
  917. void
  918. CFtpWizUserIsolation::SetControlStates()
  919. {
  920. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  921. //SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
  922. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT);
  923. }
  924. //
  925. // Message Map
  926. //
  927. BEGIN_MESSAGE_MAP(CFtpWizUserIsolation, CIISWizardPage)
  928. //{{AFX_MSG_MAP(CFtpWizUserIsolation)
  929. //}}AFX_MSG_MAP
  930. END_MESSAGE_MAP()
  931. //
  932. // Message Handlers
  933. //
  934. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  935. BOOL
  936. CFtpWizUserIsolation::OnSetActive()
  937. {
  938. if (m_pSettings->m_VersionMajor < 6)
  939. {
  940. return 0;
  941. }
  942. SetControlStates();
  943. return CIISWizardPage::OnSetActive();
  944. }
  945. LRESULT
  946. CFtpWizUserIsolation::OnWizardNext()
  947. {
  948. if (!UpdateData(TRUE))
  949. {
  950. return -1;
  951. }
  952. return CIISWizardPage::OnWizardNext();
  953. }
  954. ////////////////// User Isolation AD page //////////////////////////////////////////////////////
  955. IMPLEMENT_DYNCREATE(CFtpWizUserIsolationAD, CIISWizardPage)
  956. CFtpWizUserIsolationAD::CFtpWizUserIsolationAD(
  957. IN OUT CFtpWizSettings * pSettings,
  958. IN BOOL bVDir
  959. )
  960. : CIISWizardPage(
  961. CFtpWizUserIsolationAD::IDD,
  962. IDS_FTP_NEW_SITE_WIZARD,
  963. HEADER_PAGE,
  964. USE_DEFAULT_CAPTION,
  965. USE_DEFAULT_CAPTION
  966. ),
  967. m_bVDir(bVDir),
  968. m_pSettings(pSettings)
  969. {
  970. //{{AFX_DATA_INIT(CFtpWizPermissions)
  971. //}}AFX_DATA_INIT
  972. }
  973. CFtpWizUserIsolationAD::~CFtpWizUserIsolationAD()
  974. {
  975. }
  976. void
  977. CFtpWizUserIsolationAD::DoDataExchange(
  978. IN CDataExchange * pDX
  979. )
  980. {
  981. CIISWizardPage::DoDataExchange(pDX);
  982. //{{AFX_DATA_MAP(CFtpWizPermissions)
  983. DDX_Control(pDX, IDC_EDIT_USERNAME, m_edit_UserName);
  984. //}}AFX_DATA_MAP
  985. DDX_Text(pDX, IDC_EDIT_USERNAME, m_pSettings->m_strIsolationUserName);
  986. DDV_MaxCharsBalloon(pDX, m_pSettings->m_strIsolationUserName, UNLEN);
  987. //
  988. // Some people have a tendency to add "\\" before
  989. // the computer name in user accounts. Fix this here.
  990. //
  991. m_pSettings->m_strIsolationUserName.TrimLeft();
  992. while (*m_pSettings->m_strIsolationUserName == '\\')
  993. {
  994. m_pSettings->m_strIsolationUserName = m_pSettings->m_strIsolationUserName.Mid(2);
  995. }
  996. if (!m_fOnBack)
  997. {
  998. //DDX_Password(pDX, IDC_EDIT_PASSWORD, m_pSettings->m_strIsolationUserPassword, g_lpszDummyPassword);
  999. DDX_Password_SecuredString(pDX, IDC_EDIT_PASSWORD, m_pSettings->m_strIsolationUserPassword, g_lpszDummyPassword);
  1000. //DDV_MaxCharsBalloon(pDX, m_pSettings->m_strIsolationUserPassword, PWLEN);
  1001. DDV_MaxCharsBalloon_SecuredString(pDX, m_pSettings->m_strIsolationUserPassword, PWLEN);
  1002. }
  1003. DDX_Text(pDX, IDC_EDIT_DOMAIN, m_pSettings->m_strIsolationDomain);
  1004. DDV_MaxCharsBalloon(pDX, m_pSettings->m_strIsolationDomain, MAX_PATH);
  1005. #if 0
  1006. if (pDX->m_bSaveAndValidate && !m_fOnBack)
  1007. {
  1008. // we could have domain1\user and domain2 case, so this is wrong
  1009. CString name = m_pSettings->m_strIsolationDomain;
  1010. if (!name.IsEmpty())
  1011. {
  1012. name += _T('\\');
  1013. }
  1014. name += m_pSettings->m_strIsolationUserName;
  1015. CString csTempPassword;
  1016. m_pSettings->m_strIsolationUserPassword.CopyTo(csTempPassword);
  1017. CError err(CComAuthInfo::VerifyUserPassword(name, csTempPassword));
  1018. // CError err(IsValidDomainUser(name, m_pSettings->m_strIsolationUserPassword));
  1019. if (err.MessageBoxOnFailure(m_hWnd))
  1020. {
  1021. SetWizardButtons(PSWIZB_BACK);
  1022. pDX->PrepareEditCtrl(IDC_EDIT_PASSWORD);
  1023. pDX->Fail();
  1024. }
  1025. }
  1026. #endif
  1027. }
  1028. void
  1029. CFtpWizUserIsolationAD::SetControlStates()
  1030. {
  1031. DWORD dwFlags = PSWIZB_BACK;
  1032. if ( GetDlgItem(IDC_EDIT_USERNAME)->GetWindowTextLength() > 0
  1033. && GetDlgItem(IDC_EDIT_PASSWORD)->GetWindowTextLength() > 0
  1034. && GetDlgItem(IDC_EDIT_DOMAIN)->GetWindowTextLength() > 0
  1035. )
  1036. {
  1037. dwFlags |= PSWIZB_NEXT;
  1038. }
  1039. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  1040. //SetWizardButtons(dwFlags);
  1041. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, dwFlags);
  1042. GetDlgItem(IDC_BUTTON_BROWSE_DOMAINS)->EnableWindow(m_fInDomain);
  1043. }
  1044. //
  1045. // Message Map
  1046. //
  1047. BEGIN_MESSAGE_MAP(CFtpWizUserIsolationAD, CIISWizardPage)
  1048. //{{AFX_MSG_MAP(CFtpWizUserIsolationAD)
  1049. ON_BN_CLICKED(IDC_BUTTON_BROWSE_USERS, OnBrowseUsers)
  1050. ON_BN_CLICKED(IDC_BUTTON_BROWSE_DOMAINS, OnBrowseDomains)
  1051. ON_EN_CHANGE(IDC_EDIT_USERNAME, OnChangeUserName)
  1052. ON_EN_CHANGE(IDC_EDIT_PASSWORD, OnControlsChanged)
  1053. ON_EN_CHANGE(IDC_EDIT_DOMAIN, OnControlsChanged)
  1054. //}}AFX_MSG_MAP
  1055. END_MESSAGE_MAP()
  1056. //
  1057. // Message Handlers
  1058. //
  1059. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1060. BOOL
  1061. CFtpWizUserIsolationAD::OnInitDialog()
  1062. {
  1063. m_fOnBack = FALSE;
  1064. m_fOnNext = FALSE;
  1065. CIISWizardPage::OnInitDialog();
  1066. // Check if computer is joined to domain
  1067. COMPUTER_NAME_FORMAT fmt = ComputerNamePhysicalDnsDomain;
  1068. TCHAR buf[MAX_PATH];
  1069. DWORD n = MAX_PATH;
  1070. m_fInDomain = (GetComputerNameEx(fmt, buf, &n) && n > 0);
  1071. return TRUE;
  1072. }
  1073. BOOL
  1074. CFtpWizUserIsolationAD::OnSetActive()
  1075. {
  1076. if (m_pSettings->m_VersionMajor < 6 || m_pSettings->m_UserIsolation != 2)
  1077. {
  1078. return 0;
  1079. }
  1080. m_fOnBack = FALSE;
  1081. m_fOnNext = FALSE;
  1082. if (m_pSettings->m_strIsolationUserName.IsEmpty())
  1083. {
  1084. m_pSettings->m_strIsolationUserName = m_pSettings->m_strUserName;
  1085. m_pSettings->m_strIsolationUserPassword = m_pSettings->m_strPassword;
  1086. }
  1087. SetControlStates();
  1088. return CIISWizardPage::OnSetActive();
  1089. }
  1090. LRESULT
  1091. CFtpWizUserIsolationAD::OnWizardNext()
  1092. {
  1093. if (!ValidateString(m_edit_UserName, m_pSettings->m_strIsolationUserName,
  1094. 1, UNLEN))
  1095. {
  1096. return -1;
  1097. }
  1098. m_fOnNext = TRUE;
  1099. return CIISWizardPage::OnWizardNext();
  1100. }
  1101. LRESULT
  1102. CFtpWizUserIsolationAD::OnWizardBack()
  1103. {
  1104. m_fOnBack = TRUE;
  1105. return CIISWizardPage::OnWizardNext();
  1106. }
  1107. void
  1108. CFtpWizUserIsolationAD::OnBrowseUsers()
  1109. {
  1110. CString str;
  1111. if (GetIUsrAccount(m_pSettings->m_strServerName, this, str))
  1112. {
  1113. //
  1114. // If a name was selected, blank
  1115. // out the password
  1116. //
  1117. GetDlgItem(IDC_EDIT_USERNAME)->SetWindowText(str);
  1118. GetDlgItem(IDC_EDIT_PASSWORD)->SetFocus();
  1119. }
  1120. }
  1121. void
  1122. CFtpWizUserIsolationAD::OnBrowseDomains()
  1123. {
  1124. GetDlgItem(IDC_EDIT_DOMAIN)->GetWindowText(m_pSettings->m_strIsolationDomain);
  1125. CString prev = m_pSettings->m_strIsolationDomain;
  1126. CComPtr<IDsBrowseDomainTree> spDsDomains;
  1127. CError err = ::CoCreateInstance(CLSID_DsDomainTreeBrowser,
  1128. NULL,
  1129. CLSCTX_INPROC_SERVER,
  1130. IID_IDsBrowseDomainTree,
  1131. reinterpret_cast<void **>(&spDsDomains));
  1132. if (err.Succeeded())
  1133. {
  1134. CString csTempPassword;
  1135. m_pSettings->m_strIsolationUserPassword.CopyTo(csTempPassword);
  1136. err = spDsDomains->SetComputer(m_pSettings->m_strServerName,
  1137. m_pSettings->m_strIsolationUserName, csTempPassword);
  1138. if (err.Succeeded())
  1139. {
  1140. LPTSTR pDomainPath = NULL;
  1141. err = spDsDomains->BrowseTo(m_hWnd, &pDomainPath,
  1142. /*DBDTF_RETURNINOUTBOUND |*/ DBDTF_RETURNEXTERNAL | DBDTF_RETURNMIXEDDOMAINS);
  1143. if (err.Succeeded() && pDomainPath != NULL)
  1144. {
  1145. m_pSettings->m_strIsolationDomain = pDomainPath;
  1146. if (m_pSettings->m_strIsolationDomain.CompareNoCase(prev) != 0)
  1147. {
  1148. GetDlgItem(IDC_EDIT_DOMAIN)->SetWindowText(m_pSettings->m_strIsolationDomain);
  1149. OnControlsChanged();
  1150. }
  1151. CoTaskMemFree(pDomainPath);
  1152. }
  1153. // When user clicks on Cancel in this browser, it returns 80070001 (Incorrect function).
  1154. // I am not quite sure what does it mean. We are filtering out the case when domain browser doesn't
  1155. // work at all (in workgroup), so here we could safely skip error processing.
  1156. // else
  1157. // {
  1158. // err.MessageBox();
  1159. // }
  1160. }
  1161. }
  1162. }
  1163. void
  1164. CFtpWizUserIsolationAD::OnChangeUserName()
  1165. {
  1166. GetDlgItem(IDC_EDIT_PASSWORD)->SetWindowText(_T(""));
  1167. SetControlStates();
  1168. }
  1169. void
  1170. CFtpWizUserIsolationAD::OnControlsChanged()
  1171. {
  1172. SetControlStates();
  1173. }
  1174. ///////////////////////////////////////////
  1175. IMPLEMENT_DYNCREATE(CFtpWizPermissions, CIISWizardPage)
  1176. CFtpWizPermissions::CFtpWizPermissions(
  1177. IN OUT CFtpWizSettings * pSettings,
  1178. IN BOOL bVDir
  1179. )
  1180. /*++
  1181. Routine Description:
  1182. Constructor
  1183. Arguments:
  1184. CString & strServerName : Server name
  1185. BOOL bVDir : TRUE if this is a vdir page,
  1186. FALSE if this is an instance page
  1187. Return Value:
  1188. None
  1189. --*/
  1190. : CIISWizardPage(
  1191. CFtpWizPermissions::IDD,
  1192. (bVDir ? IDS_FTP_NEW_VDIR_WIZARD : IDS_FTP_NEW_SITE_WIZARD),
  1193. HEADER_PAGE,
  1194. (bVDir ? USE_DEFAULT_CAPTION : IDS_FTP_NEW_SITE_PERMS_TITLE),
  1195. (bVDir ? USE_DEFAULT_CAPTION : IDS_FTP_NEW_SITE_PERMS_SUBTITLE)
  1196. ),
  1197. m_bVDir(bVDir),
  1198. m_pSettings(pSettings)
  1199. {
  1200. //{{AFX_DATA_INIT(CFtpWizPermissions)
  1201. //}}AFX_DATA_INIT
  1202. m_pSettings->m_fRead = TRUE;
  1203. m_pSettings->m_fWrite = FALSE;
  1204. }
  1205. CFtpWizPermissions::~CFtpWizPermissions()
  1206. {
  1207. }
  1208. void
  1209. CFtpWizPermissions::DoDataExchange(
  1210. IN CDataExchange * pDX
  1211. )
  1212. {
  1213. CIISWizardPage::DoDataExchange(pDX);
  1214. //{{AFX_DATA_MAP(CFtpWizPermissions)
  1215. //}}AFX_DATA_MAP
  1216. DDX_Check(pDX, IDC_CHECK_READ, m_pSettings->m_fRead);
  1217. DDX_Check(pDX, IDC_CHECK_WRITE, m_pSettings->m_fWrite);
  1218. }
  1219. void
  1220. CFtpWizPermissions::SetControlStates()
  1221. {
  1222. // for some reason, bug:206328 happens when we use SetWizardButtons, use SendMessage instead.
  1223. //SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
  1224. ::SendMessage(::GetParent(m_hWnd), PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT);
  1225. }
  1226. //
  1227. // Message Map
  1228. //
  1229. BEGIN_MESSAGE_MAP(CFtpWizPermissions, CIISWizardPage)
  1230. //{{AFX_MSG_MAP(CFtpWizPermissions)
  1231. //}}AFX_MSG_MAP
  1232. END_MESSAGE_MAP()
  1233. //
  1234. // Message Handlers
  1235. //
  1236. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1237. BOOL
  1238. CFtpWizPermissions::OnSetActive()
  1239. {
  1240. SetControlStates();
  1241. return CIISWizardPage::OnSetActive();
  1242. }
  1243. LRESULT
  1244. CFtpWizPermissions::OnWizardNext()
  1245. {
  1246. if (!UpdateData(TRUE))
  1247. {
  1248. return -1;
  1249. }
  1250. ASSERT(m_pSettings != NULL);
  1251. CWaitCursor wait;
  1252. CError err;
  1253. BOOL fRepeat;
  1254. //
  1255. // Build permissions DWORD
  1256. //
  1257. DWORD dwPermissions = 0L;
  1258. SET_FLAG_IF(m_pSettings->m_fRead, dwPermissions, MD_ACCESS_READ);
  1259. SET_FLAG_IF(m_pSettings->m_fWrite, dwPermissions, MD_ACCESS_WRITE);
  1260. // if UserIsolation 2 is selected
  1261. // then Permissions must be set to specific values
  1262. if (m_pSettings->m_UserIsolation == 2)
  1263. {
  1264. SET_FLAG_IF(TRUE, dwPermissions, MD_ACCESS_NO_PHYSICAL_DIR);
  1265. }
  1266. if (m_bVDir)
  1267. {
  1268. //
  1269. // First see if by any chance this name already exists
  1270. //
  1271. CMetabasePath target(FALSE,
  1272. m_pSettings->m_strParent, m_pSettings->m_strAlias);
  1273. CChildNodeProps node(
  1274. m_pSettings->m_pKey,
  1275. target);
  1276. do
  1277. {
  1278. fRepeat = FALSE;
  1279. err = node.LoadData();
  1280. if (err.Win32Error() == RPC_S_SERVER_UNAVAILABLE)
  1281. {
  1282. err = RebindInterface(
  1283. m_pSettings->m_pKey,
  1284. &fRepeat,
  1285. ERROR_CANCELLED
  1286. );
  1287. }
  1288. } while (fRepeat);
  1289. if (err.Succeeded())
  1290. {
  1291. BOOL fNotUnique = TRUE;
  1292. //
  1293. // If the item existed without a VrPath, we'll just blow it
  1294. // away, as a vdir takes presedence over a directory/file.
  1295. //
  1296. if (node.GetPath().IsEmpty())
  1297. {
  1298. err = CChildNodeProps::Delete(
  1299. m_pSettings->m_pKey,
  1300. m_pSettings->m_strParent,
  1301. m_pSettings->m_strAlias
  1302. );
  1303. fNotUnique = !err.Succeeded();
  1304. }
  1305. //
  1306. // This one already exists and exists as a virtual
  1307. // directory, so away with it.
  1308. //
  1309. if (fNotUnique)
  1310. {
  1311. ::AfxMessageBox(IDS_ERR_ALIAS_NOT_UNIQUE);
  1312. return IDD_FTP_NEW_DIR_ALIAS;
  1313. }
  1314. }
  1315. //
  1316. // Create new vdir
  1317. //
  1318. do
  1319. {
  1320. fRepeat = FALSE;
  1321. CString csTempPassword;
  1322. m_pSettings->m_strPassword.CopyTo(csTempPassword);
  1323. err = CChildNodeProps::Add(
  1324. m_pSettings->m_pKey,
  1325. m_pSettings->m_strParent,
  1326. m_pSettings->m_strAlias, // Desired alias name
  1327. m_pSettings->m_strAlias, // Name returned here (may differ)
  1328. &dwPermissions, // Permissions
  1329. NULL, // dir browsing
  1330. m_pSettings->m_strPath, // Physical path of this directory
  1331. (m_pSettings->m_fUNC ? (LPCTSTR)m_pSettings->m_strUserName : NULL),
  1332. (m_pSettings->m_fUNC ? (LPCTSTR)csTempPassword : NULL),
  1333. TRUE // Name must be unique
  1334. );
  1335. if (err.Win32Error() == RPC_S_SERVER_UNAVAILABLE)
  1336. {
  1337. err = RebindInterface(
  1338. m_pSettings->m_pKey,
  1339. &fRepeat,
  1340. ERROR_CANCELLED
  1341. );
  1342. }
  1343. } while (fRepeat);
  1344. }
  1345. else
  1346. {
  1347. //
  1348. // Create new instance
  1349. //
  1350. do
  1351. {
  1352. fRepeat = FALSE;
  1353. CString csTempPassword;
  1354. m_pSettings->m_strPassword.CopyTo(csTempPassword);
  1355. err = CFTPInstanceProps::Add(
  1356. m_pSettings->m_pKey,
  1357. SZ_MBN_FTP,
  1358. m_pSettings->m_strPath,
  1359. (m_pSettings->m_fUNC ? (LPCTSTR)m_pSettings->m_strUserName : NULL),
  1360. (m_pSettings->m_fUNC ? (LPCTSTR)csTempPassword : NULL),
  1361. m_pSettings->m_strDescription,
  1362. m_pSettings->m_strBinding,
  1363. NULL,
  1364. &dwPermissions,
  1365. NULL,
  1366. NULL,
  1367. &m_pSettings->m_dwInstance
  1368. );
  1369. if (err.Win32Error() == RPC_S_SERVER_UNAVAILABLE)
  1370. {
  1371. err = RebindInterface(
  1372. m_pSettings->m_pKey,
  1373. &fRepeat,
  1374. ERROR_CANCELLED
  1375. );
  1376. }
  1377. } while (fRepeat);
  1378. if (err.Succeeded())
  1379. {
  1380. CMetabasePath path(SZ_MBN_FTP, m_pSettings->m_dwInstance);
  1381. // Add user isolation stuff
  1382. if (m_pSettings->m_VersionMajor >= 6)
  1383. {
  1384. CMetaKey mk(m_pSettings->m_pKey, path, METADATA_PERMISSION_WRITE);
  1385. err = mk.QueryResult();
  1386. if (err.Succeeded())
  1387. {
  1388. err = mk.SetValue(MD_USER_ISOLATION, m_pSettings->m_UserIsolation);
  1389. if (err.Succeeded() && m_pSettings->m_UserIsolation == 2)
  1390. {
  1391. err = mk.SetValue(MD_AD_CONNECTIONS_USERNAME, m_pSettings->m_strIsolationUserName);
  1392. err = mk.SetValue(MD_AD_CONNECTIONS_PASSWORD, m_pSettings->m_strIsolationUserPassword);
  1393. err = mk.SetValue(MD_DEFAULT_LOGON_DOMAIN, m_pSettings->m_strIsolationDomain);
  1394. /*
  1395. when creating an FTP site with AD User Isolation (UIM=2), the AllowAnonymous property inherited from the service level allows anonymous access, but the anonymous user is not configured. This may lead to anonymous access to the C:\ on the FTP server. We must block this.
  1396. For UIM=2, add set the property at the site level:
  1397. AllowAnonymous="FALSE"
  1398. */
  1399. err = mk.SetValue(MD_ALLOW_ANONYMOUS, FALSE);
  1400. }
  1401. }
  1402. }
  1403. // Start new site
  1404. CInstanceProps ip(m_pSettings->m_pKey->QueryAuthInfo(), path);
  1405. err = ip.LoadData();
  1406. if (err.Succeeded())
  1407. {
  1408. if (ip.m_dwState != MD_SERVER_STATE_STARTED)
  1409. {
  1410. err = ip.ChangeState(MD_SERVER_COMMAND_START);
  1411. }
  1412. }
  1413. }
  1414. }
  1415. m_pSettings->m_hrResult = err;
  1416. return CIISWizardPage::OnWizardNext();
  1417. }
  1418. /////////////////////////////////////////////////////////////////////////////////////////////
  1419. HRESULT
  1420. RebindInterface(
  1421. OUT IN CMetaInterface * pInterface,
  1422. OUT BOOL * pfContinue,
  1423. IN DWORD dwCancelError
  1424. )
  1425. /*++
  1426. Routine Description:
  1427. Rebind the interface
  1428. Arguments:
  1429. CMetaInterface * pInterface : Interface to rebind
  1430. BOOL * pfContinue : Returns TRUE to continue.
  1431. DWORD dwCancelError : Return code on cancel
  1432. Return Value:
  1433. HRESULT
  1434. --*/
  1435. {
  1436. CError err;
  1437. CString str, strFmt;
  1438. ASSERT(pInterface != NULL);
  1439. ASSERT(pfContinue != NULL);
  1440. VERIFY(strFmt.LoadString(IDS_RECONNECT_WARNING));
  1441. str.Format(strFmt, (LPCTSTR)pInterface->QueryServerName());
  1442. if (*pfContinue = (YesNoMessageBox(str)))
  1443. {
  1444. //
  1445. // Attempt to rebind the handle
  1446. //
  1447. err = pInterface->Regenerate();
  1448. }
  1449. else
  1450. {
  1451. //
  1452. // Do not return an error in this case.
  1453. //
  1454. err = dwCancelError;
  1455. }
  1456. return err;
  1457. }